【问题标题】:Cannot change label text after performing segue执行 segue 后无法更改标签文本
【发布时间】:2023-03-12 21:39:01
【问题描述】:

我有一个主 ViewController,它将一个字符串发送到第二个视图控制器,如下所示:

        if segue.identifier == "statsSegue" {
        let recievingVC:StatisticsVC = segue.destination as! StatisticsVC

        var recievingview:StatisticsView
        for View in recievingVC.view.subviews {
            if View is StatisticsView {
                recievingview = View as! StatisticsView
                recievingview.setLabel(data: "673")
            }
        }
    }

当 segue 发生时,标签正确显示为 673。但是,在第二个 ViewController 中,如果我尝试执行类似的 setLabel 它不会更改显示的标签:

    override func viewDidLoad() {
    super.viewDidLoad()
    let potato:StatisticsView = self.view.subviews[0] as! StatisticsView
    potato.GamesWonNum.text = String(580)

忽略土豆变量,它是一个占位符。上面第一个 sn-p 中的 SetLabel() 只需调用 GamesWonNum.text

那么为什么标签在 segue 中正确更改,但在我正在进入的 viewController 的 viewDidLoad 方法中没有更改?

谢谢

【问题讨论】:

    标签: ios swift uiview uiviewcontroller


    【解决方案1】:

    因为您正在访问recievingVC 的视图,这意味着将调用viewDidLoad()(因此确实加载了名称视图)。在调用viewDidLoad() 之后,您再次将标签更改为673。要解决此问题,您可以更改viewWillAppear() 中的文本。

    class StatisticsVC: UIViewController {
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            let potato = view.subviews[0] as! StatisticsView // You should just have "potato" as a property
            potato.GamesWonNum.text = "580"                  // GamesWonNum should be called "gamesWonNum"
        }
    }
    
    class TestViewController: UIViewController {
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "statsSegue" {
                segue.destination.view.subviews.forEach { ($0 as? StatisticsView)?.setLabel(data: "673") }
            }
        }
    }
    

    【讨论】:

    • 谢谢!那解决了它。那么访问prepareForSegue 中的视图是否意味着viewDidLoad() 函数已经被调用?我理解对吗?你所说的“你应该把‘土豆’作为财产”到底是什么意思?
    • viewDidLoad() 将在视图控制器的视图被访问时被调用,而不仅仅是在prepareForSegue 中。因为您使用.subviews[0] 访问potato,所以我假设您没有potato 作为属性。如果你这样做了,你就不需要该行,并且可以使用 potato.GamesWonNum.text = "580" 更改文本。
    • 我明白了!非常感谢,帮了大忙!
    【解决方案2】:

    您不应该尝试操纵另一个视图控制器的视图层次结构。这违反了封装原则,这是一个重要的 OO 概念。相反,您应该向目标视图控制器添加属性,用于传递要显示的信息,并在目标视图控制器的 viewDidLoad 或 viewWillAppear 中安装数据。

    此外,硬编码视图控制器以期望特定视图在其子视图中的固定索引处是一个坏主意。那是脆弱的。如果您稍后重新构建视图层次结构,该代码将中断。相反,您应该创建一个出口或将其链接起来,或者在视图上设置一个标签并使用该标签来找到所需的子视图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多