iOS: A Beautiful Way of Styling IBOutlets in Swift
This morning I saw a beautiful tweet from @jesse_squires:
#Swift tip: Use didSet on your IBOutlets to configure views instead of cramming code into viewDidLoad. Much cleaner. Still called only once.
— Jesse Squires (@jesse_squires) July 29, 2015
Settings colors, fonts, and accessibility for UI elements in apps is always in pain. Ideally this would happen in the storyboard, but color management in the storyboard is pretty horrible (one way to mitigate this is through an Xcode Color Palette), and more advanced accessibility stuff can’t even be done in the storyboard.
So I personally prefer to do this in code – much easier to see where all the colors / font / accessibility / etc changes need to be made when the app is re-designed. I often see this translated into a super long viewDidLoad as Jesse mentions, which I try to extract into one or more functions in private extension in Swift like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import UIKit class ViewController: UIViewController { @IBOutlet weak var myLabel: UILabel! @IBOutlet weak var myOtherLabel: UILabel! @IBOutlet weak var myButton: UIButton! override func viewDidLoad() { super.viewDidLoad() // extract this into a private function // to keep viewDidLoad short configureStyling() } } // MARK: UI Styling private extension ViewController { func configureStyling() { myLabel.textColor = UIColor.purpleColor() myOtherLabel.textColor = UIColor.yellowColor() myButton.tintColor = UIColor.magentaColor() } } |
But I really love the readability and simplicity of Jesse’s solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import UIKit class ViewController: UIViewController { @IBOutlet weak var myLabel: UILabel! { didSet { myLabel.textColor = UIColor.purpleColor() } } @IBOutlet weak var myOtherLabel: UILabel! { didSet { myOtherLabel.textColor = UIColor.yellowColor() } } @IBOutlet weak var myButton: UIButton! { didSet { myButton.tintColor = UIColor.magentaColor() } } override func viewDidLoad() { super.viewDidLoad() } } |
Time to refactor!