Search code examples
swiftmultithreadinggrand-central-dispatchdispatch-asyncbackground-thread

Initialising UIView in main thread from a background thread


In a global, async closure, I'd like to initialise a UIView on the main thread. I thought this code would possibly do it, but I get an Analyser warning:

UIView.init(frame:) must by used from the main thread only.

let view: UIView = { // Line with the warning
      DispatchQueue.main.sync {
          return UIView()
      }
}()

Solution

  • I'll be helpful if u post more of the code so we could understand the context better. Anyway, this should work nicely:

    class SomeViewController: UIViewController {
    
        private var customView: UIView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            setupCustomView()
        }
    
        private func setupCustomView() {
            DispatchQueue.global().async {
                /*
                 1. Do some preperation / data init' on background thread.
                 2. When ready, perform UI dependent initialization on main thread.
                 */
                DispatchQueue.main.async {
    
                    /* Initialize `customView` on the main queue. for example: */
                    self.customView = UIView()
                    self.view.addSubview(self.customView)
                    self.customView.backgroundColor = .red
                    self.customView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
                }
            }
        }
    }
    

    I hope that helps.