prepareForSegue在viewDidLoad加载所有IBOutlets之前触发didSet

时间:2015-04-15 05:44:55

标签: ios swift

我有一个非常简单的设置,其中显示TableViewController内的用户列表。每当用户点击其中一行时,他就会被定向到该用户的个人资料。

case "ShowProfileSegue":
  let profileVC = segue.destinationViewController as! ProfileViewController
  let cell = sender as! SearchResultTableViewCell
  profileVC.user = cell.user
  break

在我的ProfileViewController我有以下didSet回调:

var user : User {
    didSet {
        if let newUser = self.user {
            profileNameLabel.text = newUser.name
            profileDescriptionLabel.text = ", ".join(newUser.roles)
        }
    }
}

问题是每当didSet回调运行时,我的两个标签都会nil导致程序崩溃。我认为使用didSet来更新UI非常漂亮,但显然它似乎并不总是有效。我还有哪些其他方法可以处理这个用例?

Crash

4 个答案:

答案 0 :(得分:2)

如果标签为零,只需将didSet保释:

var user : User {
    didSet {
        if profileNameLabel != nil { // bail out if still nil
            if let newUser = self.user {
                profileNameLabel.text = newUser.name
                profileDescriptionLabel.text = ", ".join(newUser.roles)
            }
        }
    }
}

调用viewDidLoad后,将加载出口并且标签不会为零,现在您的didSet将非常有用。在此之前,没有配置界面!

答案 1 :(得分:2)

你可以这样做:

 var appDetail: AppDetail? {
        didSet {
            if let d = appDetail, let _ = view {
                nameLabel.text = d.info.name
                iconImageView.setImageWithURL(d.detail.iconURL)
                descriptionLabel.text = d.detail.introduction
            }
        }
    }

事实上,let _ = view将加载视图,所有IBOutlet将不再为零。

答案 2 :(得分:1)

您需要在profileNameLabel和profileDescriptionLabel中使用didSet,例如:

@IBOutlet weak var profileNameLabel: UILabel! {
    didSet {
        profileNameLabel.text = user.name
    }
}

因为现在你在实际的segue之前设置了用户(准备 ForSegue),这就是为什么你不能在那时设置你的出口。将属性观察者添加到出口是了解何时设置的好方法。

答案 3 :(得分:1)

您也可以像这样使用loadViewIfNeeded()

var user : User {
    didSet {
        loadViewIfNeeded()
        if let newUser = self.user {
            profileNameLabel.text = newUser.name
            profileDescriptionLabel.text = ", ".join(newUser.roles)
        }
    }
}