Josh Paradroid
Josh Paradroid

Reputation: 1414

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()
      }
}()

Upvotes: 1

Views: 4653

Answers (2)

Mannopson
Mannopson

Reputation: 2684

Try something like that:

You can keep using your own implementation, without DispatchQueue.main.sync

let view: UIView = { 
      return UIView()
}()

However you can go back to the main thread anytime:

DispatchQueue.main.async {
  self.view.addSubview(view) 
}

Use the .async, it's gives you an independent thread

Upvotes: 0

DanielH
DanielH

Reputation: 685

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.

Upvotes: 3

Related Questions