When using Objective-C, I used to initialize properties for some of the elements in the ViewController like this:
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *welcomeMessageLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initView];
}
- (void)initView {
self.welcomeMessageLabel.numberOfLines = 0;
self.welcomeMessageLabel.text = @"Welcom to the application!";
self.welcomeMessageLabel.textColor = [UIColor redColor];
self.welcomeMessageLabel.backgroundColor = [UIColor clearColor];
}
@end
Inside the method initView I would write the logic to preset how elements should look and behave. The problem with this – as more and more properties or outlets get added – the more I have to write inside initView.
In Swift, this can be elegantly solved using a closure to provide default property value:
let welcomeMessageLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.text = "Welcome to the application"
label.backgroundColor = UIColor.redColor()
return label
}()
Note that you should add () after the closure so that it can be immediately executed. Without the parentheses you are trying to assigning the closure itself to the property, and not the result of its execution.
If we need to provide default logic for IBOutlet, like the first example, then we can use the following:
class ViewController : UIViewController {
@IBOutlet weak var welcomeMessageLabel: UILabel! {
didSet {
welcomeMessageLabel.numberOfLines = 0
welcomeMessageLabel.text = "Welcome to the application"
welcomeMessageLabel.textColor = UIColor.redColor()
welcomeMessageLabel.backgroundColor = UIColor.blackColor()
}
}
}
