【问题标题】:Passing data between Tab Bar Controllers with NSNotificationCenter in Swift在 Swift 中使用 NSNotificationCenter 在选项卡栏控制器之间传递数据
【发布时间】:2015-02-23 08:08:23
【问题描述】:

我第一次尝试在标签栏控制器之间传递数据,但它不起作用。 第一控制器:

class FirstViewController: UIViewController {
@IBOutlet weak var sentNotificationLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateNotificationSentLabel:", name: mySpecialNotificationKey, object: nil)
}

@IBAction func notify() {
    NSNotificationCenter.defaultCenter().postNotificationName(mySpecialNotificationKey, object: nil, userInfo:["message":"Something"])
}

func updateNotificationSentLabel(notification:NSNotification) {
    let userInfo:Dictionary<String,String!> = notification.userInfo as Dictionary<String,String!>
    let messageString = userInfo["message"]
    sentNotificationLabel.text = messageString


}
}

这里没问题,sentNotificationLabel.text 是“Something”

第二个控制者类似,但他没有收到任何通知。

class SecondViewController: UIViewController {
@IBOutlet weak var notificationLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateLabel:", name: mySpecialNotificationKey, object: nil)
}

func updateLabel(notification:NSNotification) {
    let userInfo:Dictionary<String,String!> = notification.userInfo as Dictionary<String,String!>
    let messageString = userInfo["message"]
    notificationLabel.text = messageString


}

}

我做错了什么?如何改变它?

【问题讨论】:

  • 您能否描述一下您是如何检查通知未通过的?请记住,在用户选择之前,不会加载第二个选项卡中显示的视图控制器。
  • 好的,你是对的。当我第一次选择第二个标签栏并返回到第一个控制器时,它就可以工作了。我可以在此之前加载它吗?

标签: ios swift uitabbarcontroller nsnotificationcenter message-passing


【解决方案1】:

出现问题是因为您在注册第二个视图控制器之前发送消息。

NSNotificationCenter 不支持 sticky 通知 - 换句话说,消息不会被缓存。如果在发送通知的那一刻没有人在听,它就消失了。

最简单的解决方法是在初始化程序中注册您的SecondViewController 以获取通知。但是,UILabel 尚未加载 - 我们在 viewDidLoad 回调之前。解决方法是将接收到的消息缓存到本地,准备好后用它来设置标签文本。

class SecondViewController: UIViewController {

    @IBOutlet weak var notificationLabel: UILabel!
    var cachedMessage : String? = nil

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateLabel:", name: mySpecialNotificationKey, object: nil)
    }

    override func viewDidLoad() {
        if let cachedMessage = cachedMessage {
            notificationLabel.text = cachedMessage
        }
    }

    func updateLabel(notification:NSNotification) {
        let userInfo:Dictionary<String,String!> = notification.userInfo as Dictionary<String,String!>
        let messageString = userInfo["message"]
        if let notificationLabel = notificationLabel {
            notificationLabel.text = messageString
        } else {
            cachedMessage = messageString
        }
    }
}

由于控制器在显示之前已被初始化,因此应正确传递消息。

【讨论】:

  • 致命错误:在展开可选值时意外发现 nil。我认为 UILabel 是零。
  • @migari 是的,它是nil。我已经更新了回复以反映这一点。
  • 谢谢!我仍在尝试理解它,但效果很好。当 UILabel 不存在时,cacheMessage 在初始化器中接收消息,然后在 viewDidLoad 中将其传递给 UILabel?
  • @migari 就像你描述的那样,所以显然你已经明白了:) Controller 在初始化程序中注册通知,而不是通知从 FirstViewController 传递到 SecondViewController,它被缓存在 SecondViewController 中,因为UILabel 还不存在,在加载 UILabel 后,它的值被设置为显示缓存的消息。
【解决方案2】:

只需在init方法

中添加观察者
required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

     NSNotificationCenter.defaultCenter().addObserver(self, selector: "addBadge", name: "addBadge", object: nil)

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多