Styling by subclassing – The.Swift.Dev.

[ad_1]

Discover ways to design and construct reusable person interface components by utilizing customized view subclasses from the UIKit framework in Swift.

UIKit

The issue: UI, UX, design

Constructing person interfaces is the toughest a part of the job!

In a nutshell: design is a strategy of determining the very best answer that matches a particular drawback. Graphic design often means the bodily drawing on a canvas or a paper. UX is actually how the person interacts with the applying, in different phrases: the general digital expertise of the “buyer” journey. UI is the seen interface that he/she’s going to see and work together with by touching the display screen. 👆

If I’ve to placed on the designer hat (and even the developer hat) I’ve to inform you that determining and implementing correct person interfaces is essentially the most difficult drawback in many of the instances. Frontend methods these days (cellular, pill, even desktop apps) are simply fancy overlays on high of some JSON knowledge from a service / API. ðŸĪ·â€â™‚ïļ

Why is it so arduous? Nicely, I consider that if you wish to be a great designer, you want a correct engineering mindset as effectively. You need to be able to observing the complete system (massive image), assemble constant UI components (that really look the identical in all places), plan the desired expertise primarily based on the practical specification and lots of extra. It is also fairly a primary requirement to be an artist, assume outdoors of the field, and be capable to clarify (describe) your thought to others. ðŸĪŊ

Now inform me whose job is the toughest within the tech trade? Yep, as a free of charge everyone seems to be a designer these days, additionally some corporations do not rent this type of specialists in any respect, however merely let the work completed by the builders. Anyway, let’s concentrate on easy methods to create good and reusable design implementations by utilizing subclasses in Swift. 👍


Look, themes and types

Let me begin with a confession: I barely use the UIAppearance API. This can be a private choice, however I prefer to set design properties like font, textColor, backgroundColor straight on the view cases. Though in some instances I discovered the looks proxy very good, however nonetheless a little bit buggy. Perhaps this can change with iOS 13 and the arrival of the lengthy awaited darkish mode.

Expensive Apple please make an auto swap primarily based on day / evening cycles (you realize just like the sundown, dawn possibility within the house app). 🌙

  • Fashion is a group of attributes that specifiy the looks for a single view.
  • Theme is a set of comparable trying view types, utilized to the entire software.

These days I often create some predefined set of styling components, most definitely fonts, colours, however generally icons, and many others. I prefer to go together with the next construction:

Fonts

  • title
  • heading
  • subheading
  • physique
  • small

Colours

Icons

You possibly can have much more components, however for the sake of simplicity let’s simply implement these ones with a extremely easy Swift answer utilizing nested structs:

struct App {

    struct Fonts {
        static let title = UIFont.systemFont(ofSize: 32)
        static let heading = UIFont.systemFont(ofSize: 24)
        static let subheading = UIFont.systemFont(ofSize: 20)
        static let physique = UIFont.systemFont(ofSize: 16)
        static let small = UIFont.systemFont(ofSize: 14)
    }

    struct Colours {
        static let title = UIColor.blue
        static let heading = UIColor.black
        static let background = UIColor.white
    }

    struct Icons {
        static let again = UIImage(named: "BackIcon")!
        static let share = UIImage(named: "ShareIcon")!
    }

}


App.Fonts.title
App.Colours.background
App.Icons.again

This fashion I get a reasonably easy syntax, which is sweet, altough this may not let me do dynamic styling, so I can’t swap between mild / darkish theme, however I actually do not thoughts that, as a result of in many of the instances it is not a requirement. 😅

Structs vs enums:

I might use enums as an alternative of structs with static properties, however on this case I just like the simplicity of this strategy. I do not wish to fiddle with uncooked values or extensions that accepts enums. It is only a private choice.

What if it’s a must to help a number of themes?

That is not an enormous difficulty, you’ll be able to outline a protocol to your wants, and implement the required theme protocol as you need. The true drawback is when it’s a must to swap between your themes, as a result of it’s a must to refresh / reload your total UI. â™ŧïļ

There are some finest practices, for instance you need to use the NSNotificationCenter class in an effort to notify each view / controller in your app to refresh if a theme change happens. One other answer is to easily reinitialize the entire UI of the applying, so this implies you principally begin from scratch with a model new rootViewController. ðŸ˜ą

Anyway, verify the hyperlinks under for those who want one thing like this, however for those who simply wish to help darkish mode in your app, I might counsel to attend till the primary iOS 13 beta comes out. Perhaps Apple will give some shiny new API to make issues simple.


Customized views as fashion components

I promised styling by subclassing, so let’s dive into the subject. Now that we’ve a great answer to outline fonts, colours and different primary constructing blocks, it is time to apply these types to precise UI components. After all you need to use the UIAppearance API, however for instance you’ll be able to’t merely set customized fonts by the looks proxy. ðŸ˜Ē

One other factor is that I like consistency in design. So if a title is a blue, 32pt daring system font someplace in my software I additionally anticipate that component to observe the identical guideline in all places else. I clear up this drawback by creating subclasses for each single view component that has a customized fashion utilized to it. So for instance:

  • TitleLabel (blue colour, 32pt system font)
  • HeadingLabel (blue colour, 24pt system font)
  • StandardButton (blue background)
  • DestructiveButton (purple background)

One other good factor when you’ve got subclasses and also you’re working with autolayout constraints from code, that you may put all of your constraint creation logic straight into the subclass itself. Let me present you an instance:

import UIKit

class TitleLabel: UILabel {

    override init(body: CGRect) {
        tremendous.init(body: body)

        self.initialize()
    }

    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)

        self.initialize()
    }

    init() {
        tremendous.init(body: .zero)

        self.initialize()
    }

    func initialize() {
        self.translatesAutoresizingMaskIntoConstraints = false
        self.textColor = App.Colours.title
        self.font = App.Fonts.title
    }

    func constraints(in view: UIView) -> [NSLayoutConstraint] {
        return [
            self.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
            self.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
            self.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        ]
    }
}

As you’ll be able to see I solely should set the font & textColor attributes as soon as, so after the view initialization is finished, I can ensure that each single occasion of TitleLabel will look precisely the identical. The utilization is fairly easy too, you simply should set the category title in interface builder, or you’ll be able to merely create the view like this:


let titleLabel = TitleLabel()
self.view.addSubview(titleLabel)
NSLayoutConstraint.activate(titleLabel.constraints(in: self.view))

The factor I like essentially the most about this strategy is that my constraints are going to be simply in the precise place, so they will not bloat my view controller’s loadView technique. You can even create a number of constraint variations primarily based in your present state of affairs with further parameters, so it is fairly scalable for each state of affairs. 👍

View initialization is tough

The draw back of this answer is that view initialization is type of tousled, due to the interface builder help. You need to subclass each single view sort (button, label, and many others) and actually copy & paste your initialization strategies many times. I have already got some articles about this, verify the hyperlinks under. 👇

As a way to clear up this drawback I often find yourself by making a mother or father class for my very own styled views. Right here is an instance for an summary base class for my labels:

class Label: UILabel {

    override init(body: CGRect) {
        tremendous.init(body: body)

        self.initialize()
    }

    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)

        self.initialize()
    }

    init() {
        tremendous.init(body: .zero)

        self.initialize()
    }

    func initialize() {
        self.translatesAutoresizingMaskIntoConstraints = false
    }
}

So to any extent further I simply should override the initialize technique.

class TitleLabel: Label {

    override func initialize() {
        tremendous.initialize()

        self.font = App.Fonts.title
        self.textColor = App.Colours.title
    }
}

See, it is so significantly better, as a result of I haven’t got to take care of the required view initialization strategies anymore, additionally autoresizing shall be off by default. âĪïļ

My last takeaway from this lesson is that you just shouldn’t be afraid of courses and object oriented programming if it involves the UIKit framework. Protocol oriented programming (additionally practical programming) is nice for those who use it in the precise place, however since UIKit is sort of an OOP framework I consider it is nonetheless higher to observe these paradigms as an alternative of selecting some hacky means. ðŸĪŠ

In the event you like my publish, please additionally observe me on twitter, and subscribe to my month-to-month publication. It is 100% Swift solely content material, no spam ever!



[ad_2]

Leave a Reply