ios - 在 viewDidLoad 中从 Nib 解包 nil 时出现 Swift 错误

标签 ios swift

得到一些奇怪的结果,我正在加载一个我创建为自定义警报 View 的 nib 文件。但是,当它尝试更改自定义警报 View 中的 UILabel 文本时,它在 viewDidLoad 方法中失败。 (得到展开零错误)

当我转到 nib 文件时,我所有的 socket 都已连接(在它们旁边显示突出显示的点)。文件的所有者也设置为正确的类名。

然而,当代码失败并启动调试器时,所有导出都是空的。这段代码出现在 viewDidAppear 中,所以 socket 和所有 UI 不应该在那个时候加载吗?

辅助信息: 另一个奇怪的部分是,我正在两个不同的设备上对此进行测试。一个运行 iOS 8.4,另一个运行 iOS 9.1(测试版)。 iOS 9.1 设​​备运行正常,不会抛出此 nil 错误。 iOS 8.4 设备是引发错误的设备。运行 Xcode 6.4 swift 1.2。为了让代码在我的 iOS 9.1 上运行,我在我的设备连接到计算机的情况下打开 Xcode 7,然后关闭并重新打开 Xcode 6.4,它允许我将我的目标 iOS 设置为 9.1。

更新

代码失败的图片 enter image description here

Nib 文件 View Controller :

@IBOutlet var messageLabel: UILabel!
@IBOutlet var notificationHeightConstraint: NSLayoutConstraint!
@IBOutlet var notificationWidthConstraint: NSLayoutConstraint!
@IBOutlet var singleButton: UIButton!
@IBOutlet var rightButton: UIButton!
@IBOutlet var leftButton: UIButton!
@IBOutlet var middleButtonSpacerView: UIView!

var buttonDelegate: NotificationButtonDelegate?
var grayView: UIView!
var buttonTitles = [String]()
var notificationWidth: CGFloat!
var notificationHeight: CGFloat = 200.0
var hideProgressView = false
var hideNotificationView = false
var currentProgress: CGFloat = 0.0
var messageLabelText = ""


required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}

override func viewDidLoad() {
    super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    messageLabel.text = messageLabelText

    if buttonTitles.count > 0 {
        if buttonTitles.count == 1 {
            rightButton.hidden = true
            leftButton.hidden = true
            middleButtonSpacerView.hidden = true
            singleButton.setTitle("\(buttonTitles[0])", forState: UIControlState.Normal)
        } else {
            leftButton.setTitle("\(buttonTitles[0])", forState: UIControlState.Normal)
            rightButton.setTitle("\(buttonTitles[1])", forState: UIControlState.Normal)
        }
    }


    if self.hideProgressView {
        self.progressView.hidden = true
        if messageLabel.bounds.height >= 90 {
            notificationHeightConstraint.constant = 225
        } else {
            notificationHeightConstraint.constant = 200.0
        }
    }

    if self.hideNotificationView {
        self.notificationView.hidden = true
        self.activityIndicator.startAnimating()
        notificationHeightConstraint.constant = 160
    }

    self.notificationWidthConstraint.constant = notificationWidth
    self.view.needsUpdateConstraints()

    // Do any additional setup after loading the view.

}

主视图 Controller 中的自定义警报 View 类初始化

var notificationPopup: NotificationPopupViewController!
var progressPopup: NotificationPopupViewController!

override func viewDidLoad() {
    super.viewDidLoad()
    self.hasError = false
    notificationPopup = NotificationPopupViewController()
    progressPopup = NotificationPopupViewController()

在主 viewController 中调用以呈现自定义警报 View

@IBAction func configureSystemButtonTapped(sender: AnyObject) {

    var prefs: NSUserDefaults = NSUserDefaults.standardUserDefaults()
    var hostedSSID = prefs.valueForKey("HostedSSID") as? String
    var currentSSID = sureVue.getUserSSID()

    if currentSSID != hostedSSID || currentSSID == "" {
        self.notificationPopup.showInView(self.view, withMessage: "You are not connected to the device's wifi.\nFollow instructions on launch page to connect.", animated: false, buttonLabels: ["Ok"])

nib viewController 中设置自定义警报 View 的方法

    func showInView(aView: UIView!, withMessage message: String!, animated: Bool, buttonLabels:[String]) {
    self.hideNotificationView = false
    self.hideProgressView = true
    self.buttonTitles = buttonLabels
    notificationWidth = aView.bounds.width * 0.925
    grayView = UIView(frame: aView.frame)
    grayView.backgroundColor = UIColor(red: 170/255.0, green: 170/255.0, blue: 170/255.0, alpha: 0.75)
    grayView.center = CGPoint(x: aView.bounds.width/2, y: aView.bounds.height/2)
    grayView.addSubview(self.view)
    self.view.center = CGPoint(x: aView.bounds.width/2, y: aView.bounds.height/2)
    aView.addSubview(grayView)
    messageLabelText = message


    if animated
    {
        self.showAnimate()
    }
}

最佳答案

根据评论,我认为问题在于 self.notificationPopup 的初始化方式。您需要使用 init(nibName: ...),而不是 notificationPopup = NotificationPopupViewController(),以便从 nib 加载实例并设置其导出。

现有代码在 iOS 9 中工作正常,因为 Apple 已经更改了默认的 nibNames,如果您在初始化 UIViewController 时没有指定,则会使用这些默认的 nibNames。请参阅 iOS9 release notes 中 UIKit 下的注释.

关于ios - 在 viewDidLoad 中从 Nib 解包 nil 时出现 Swift 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32765221/

相关文章:

objective-c - 我应该在 Objective C 类中的什么位置设置默认变量值

iphone - 什么是像 UIKeyboardFrameEndUserInfoKey 这样的常量,用于 iphone 中的附加日文键盘面板?

ios - 扫描数组查找条件,返回索引以扫描所述索引处的 Array2 值

swift - 在 Xcode 6.0 模式中创建环境变量并从 swift 中的代码中获取它们

ios - fatal error : unexpectedly found nil while unwrapping an Optional value error Swift

ios - 如何在 SQLITE 中使用 AM/PM 按日期/时间排序

objective-c - 初始化 boolean 数组 - 返回 null

ios - 如何将文件从目录复制到iphone文档目录

swift - 将 onChanged 回调添加到 SwiftUI 结构以发出值

ios - Swift 框架可以引用另一个 Swift 框架的类扩展吗?