0

To create UIView programmatically, I can do it in two different ways. However, I have no understanding as to what the benefits or drawbacks are of each method and which is better.

What are the differences of the two methods? And what do the () and ! do differently?

Any hints would be very appreciated. Thanks.


Code

// Create UIView method 1

var myView1 = UIView()


// Create UIView method 2

var myView2: UIView!
4
  • 1
    Another way: var myView3: UIView = { // Your implementation }(), var myView4: UIView?. ! this means value is exist and it's not optional. Commented Nov 12, 2017 at 2:30
  • 2
    You did not create an UIView in your second method. You only tell the compiler that you did. If you try to access that uiview with only that code, your app will crash. Commented Nov 12, 2017 at 2:34
  • Thanks for your help Mannopson , J. Doe. Commented Nov 12, 2017 at 3:52
  • @J.Doe You are half right. The 2nd method does not create a view. But it does not tell the compiler that you did. All it does is declare an implicitly unwrapped optional. That's it. That does not suggest anything at all about the creation of the view. Commented Nov 12, 2017 at 4:12

2 Answers 2

4

The second method doesn't create a UIView, it simply declares a property that can hold a reference to a UIView. You have declared it as an implicitly unwrapped optional via !, which means that the compiler doesn't complain that you haven't initialised it, but you do still need to initialise it somewhere or you will get a runtime exception when you access it.

What you are really asking about is two slightly different ways to declare a property that can hold a reference to a UIView.

Swift requires that all properties are initialised with a value or declared as optional via ?. ! is a special case where an optional is implicitly unwrapped; The property is still an optional type, so it doesn't need to be initialised but you are telling Swift that you will initialise it and so it isn't necessarily for you to unwrap it when you use it.

For example, an @IBOutlet UIView property will be initialised when a view controller is loaded from a storyboard, so you can be confident that it will have a value (or something is misconfigured and you will get a crash), but that value isn't supplied by the initialiser, so the property needs to be an optional.

Declaring the property as an implicitly unwrapped optional makes the compiler happy even though it can't see where the property is initialised and saves you from having to conditionally unwrap the property each time you refer to it.

Your question is asking about programatically creating a UIView, so the method you use may depend on how you wanted to create the view.

If you just want a UIView and you are going to add constraints to it later, you can use:

 var myView = UIView()

 override func viewDidLoad() {
    super.viewDidLoad()
    self.myView.backgroundColor = .green
    self.myView.translatesAutoResizingMaskIntoConstraints = false
    //  Set up constraints
 }

However, if you wanted to set up the view based on the frame of the superview, you might do something like this:

 var myView: UIView!

 override func viewDidLayoutSubviews() {
     super.viewDidLayoutSubviews()

     if self.myView == nil {
         self.myView = UIView(frame:self.view.frame)
         self.myView.backgroundColor = .green
         ...
     }
 }

Generally it is best to avoid explicitly unwrapped optionals and force unwrapping unless you really are sure that it will have a value.

Sign up to request clarification or add additional context in comments.

1 Comment

Appreciate this explanation @Paulw11 I've ben using UIView() UIview! without really understanding why. Thanks.
1

The method 1 var myView1 = UIView() is always better as the second method entails force unwrapping of an optional and it may lead to crashes if during the loading of the view it doesn't find that UIView. Infact force unwrapping of optionals for UIView is discouraged unless otherwise you are creating your views in storyboards and then connecting them in your view controller as its against the very basic rule of type safety of the Swift language and rule of avoiding unpleasant surprises. As a basic rule if by doing something you know upfront it has chances of crashing in some circumstances then avoid it as Murphy law is bound to apply (Whatever can go wrong will go wrong and thats too at the most inappropriate time.) and this is the reason if you go through Swift literature almost everyone asks you to avoid force unwrapping of optionals.

1 Comment

I like surprises, but not so much in code. Thanks for explaining this further.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.