Home > Software design >  awakeFromNib vs didSet: Where to set Font or corner radius and why?
awakeFromNib vs didSet: Where to set Font or corner radius and why?

Time:03-21

I am trying to understand the difference between setting the font to a label or cornerRadius to a view in didSet of the outlet of UILabel or UIView vs doing it in awakeFromNib.

Which one is a good practice and why? Is there any performance or compilation-related reason?

@IBOutlet weak var titleLabel: UILabel! {
   didSet {
      titleLabel.font = UIFont
   }
}

vs

override func awakeFromNib() {
   super.awakeFromNib()
   // Initialization code
   titleLabel.font = UIFont
}

CodePudding user response:

If you are just setting a simple font:

titleLabel.font = UIFont(name: "SomeFamily", size: 20)

then it doesn't really matter whether you do it in didSet or awakeFromNib. However, if your font depends on the property of some other IBOutlet, like (contrived example here):

titleLabel.font = UIFont(name: anotherLabelOutlet.text!, size: 20)

Then you should definitely do it in awakeFromNib. In awakeFromNib, as it is documented:

When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.

In the didSet of titleLabel, however, it is not necessarily true that anotherLabelOutlet has been set. Outlets are set in a non-guaranteed order.

This not only applies to setting fonts, but also any initialisation that involves other outlets.

On the other hand, if you happen to reassign titleLabel somewhere down the line (for some weird reason), that new label won't get the font you set, if you set it in awakeFromNib, but will if you set it in didSet.

// in a later part of the code...
titleLabel = UILabel(frame: ...)
// titleLabel now has the new font if you set it in didSet, otherwise it won't

I would recommend that you don't think about this too much and just do it in awakeFromNib, and avoid reassigning IBOutlets in general.

CodePudding user response:

Answer for the good practice :

If the features of the component you will create are not dependent on another component, using didSet is better in terms of code readability, but I do not think there is a difference in performance.

If you have too many components, typing the properties of these components into awakefromnib may affect the code readability.

CodePudding user response:

Others have given partial information. Here is a description of the different methods you mentioned (as well as some others)

awakeFromNib() is called once after an object is loaded "from a nib archive". In modern iOS, that usually means a storyboard, although you can still load user interface elements from XIB files (the modern name for nibfiles.)

didSet is a Swift language feature that lets you attach code to a property that gets run each time that property is changed. Use code in a didSet closure for code you want to execute every time a particular property is assigned a new value.

The viewDidLoad() method is a method you can implement in your subclasses of UIViewController that gets called once, after your view controller's view hierarchy is loaded. This method is a good place to do view configuration that can't be done in a storyboard.

As others have said, if you are using storyboards, setting your label's font in the storyboard is probably the better way to go.

If you build your view controller's view hierarchy in code, you'll probably implement the loadView() method to create and configure your view controllers views. In that case it would make sense to set their font and other properties there.

If you're using SwiftUI you'll likely configure your Views in the closure you pass into their initializer.

  • Related