【问题标题】:Swift dispatch_async not updating UIView until iOS notificationSwift dispatch_async 直到 iOS 通知才更新 UIView
【发布时间】:2015-09-25 08:57:27
【问题描述】:

我有一个 UIView,一旦按下按钮就会从服务器更新。

UIView 更新发生在 dispatch_async() 中。通过调试我可以看到已经收到服务器响应,并且新的子视图被创建并应用到 UIView。

但是视图保持不变直到另一个 iOS 通知发生(例如设备收到一封电子邮件)。一旦显示通知横幅,UIView 就会刷新并显示来自服务器的图像。

我错过了什么?添加新的子视图后,如何让 UIView 立即更新?

注意:我在 dispatch_async() 内外尝试了以下操作,并尝试在初始更改发生后在同一个队列中调用它们,但运气不佳。

  • self.view.setNeedsDisplay()
  • self.view.bringSubviewToFront(view)
  • self.view.layoutIfNeeded()(感谢@buxik的建议)

EDIT添加代码(大类的小版本,仅添加相关部分):

   class networkedImage: UIViewController {
    @IBOutlet var viewArea: UIView = UIView()
    let originalWidth: CGFloat = 200
    let originalHeight: CGFloat = 100
    let imageURL: NSURL = NSURL(string: "www.example.com/image.jpg")!

    func updateViewArea() {
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
        dispatch_async(dispatch_get_main_queue()) {
          self.viewArea.subviews.forEach({ $0.removeFromSuperview() })

      let newImageView = UIImageView(frame: CGRectMake(0, 0, self.originalWidth, self.originalHeight))
      let data = NSData(contentsOfURL: self.imageURL)
      if data != nil {
        let image = UIImage(data: data!)
        if image != nil {
          newImageView.image = image

          self.viewArea.addSubview(newImageView)
          self.viewArea.bringSubviewToFront(newImageView)
          self.viewArea.setNeedsDisplay()
        }

         NSNotificationCenter.defaultCenter().addObserverForName("NotificationIdentifier", object: nil, queue: nil, usingBlock: {
         [unowned self] note in
         print("I thought this might work, it didn't.")
         })
       }
     }
   }
  }
}

【问题讨论】:

  • 也许 self.view.layoutIfNeeded()
  • @buxik 不走运,感谢您的建议。
  • 您是否在主队列上进行更新? dispatch_async(dispatch_get_main_queue())
  • 在问题中添加相关代码将帮助人们识别问题所在。没有看到这一点,它很容易由任何数量的事情引起。

标签: ios swift asynchronous uiview swift2


【解决方案1】:

为了解决这个问题,我在 viewDidLoad() 中添加了一个观察者

        NSNotificationCenter.defaultCenter().addObserverForName("imageReadyNotification", object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: {
        [unowned self] note in
        self.updateViewArea()
        })

然后在 updateViewArea() 的底部发布通知

                if self.newImage == true {
                NSNotificationCenter.defaultCenter().postNotificationName("imageReadyNotification", object: nil, userInfo: nil)
            }

if 条件是为了确保通知不会被连续触发。我不知道为什么调用这个函数两次有效,但确实有效。

【讨论】:

    猜你喜欢
    • 2017-11-10
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    相关资源
    最近更新 更多