Saturday, November 7, 2026
HomeiOS DevelopmentMastering iOS auto format anchors programmatically from Swift

Mastering iOS auto format anchors programmatically from Swift

[ad_1]

In search of finest practices of utilizing format anchors? Let’s discover ways to use the iOS autolayout system within the correct means utilizing Swift.

iOS

Creating views and constraints programmatically

To begin with I might wish to recap the UIViewController life cycle strategies, you might be may aware of a few of them. They’re being referred to as within the following order:

  • loadView
  • viewDidLoad
  • viewWillAppear
  • viewWillLayoutSubviews
  • viewDidLayoutSubviews
  • viewDidAppear

Within the pre-auto format period, you needed to do your format calcuations contained in the viewDidLayoutSubviews technique, however since this can be a professional auto format tutorial we’re solely going to concentrate on the loadView & viewDidLoad strategies. 🤓

These are the essential guidelines of making view hierarchies utilizing auto format:

  • By no means calculate frames manually by your self!
  • Initialize your views with .zero rect body
  • Set translatesAutoresizingMaskIntoConstraints to false
  • Add your view to the view hierarchy utilizing addSubview
  • Create and activate your format constraints NSLayoutConstraint.activate
  • Use loadView as a substitute of viewDidLoad for creating views with constraints
  • Care for reminiscence administration through the use of weak properties
  • Set each different property like background shade, and many others. in viewDidLoad

Sufficient concept, here’s a brief instance:

class ViewController: UIViewController {

    weak var testView: UIView!

    override func loadView() {
        tremendous.loadView()

        let testView = UIView(body: .zero)
        testView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(testView)
        NSLayoutConstraint.activate([
            testView.widthAnchor.constraint(equalToConstant: 64),
            testView.widthAnchor.constraint(equalTo: testView.heightAnchor),
            testView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            testView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
        ])
        self.testView = testView
    }

    override func viewDidLoad() {
        tremendous.viewDidLoad()

        self.testView.backgroundColor = .crimson
    }
}

Fairly easy, huh? Only a few traces of code and you’ve got a set measurement middle aligned view with a devoted class property reference. In case you create the very same by interface builder, the system will “make” you the loadView technique without cost, however you will need to setup an IBOutlet reference to the view.

The everlasting dilemma: code vs Interface Builder.

It actually does not issues, be at liberty to selected your path. Generally I like taking part in round with IB, however in a lot of the circumstances I desire the programmatic means of doing issues. 😛


Frequent UIKit auto format constraint use circumstances

So I promised that I will present you tips on how to make constraints programmatically, proper? Let’s try this now. To begin with, I take advantage of nothing however format anchors. You would waste your time with the visible format language, however that is positively a useless finish. So mark my phrases: use solely anchors or stack views, however nothing else! 😇

Listed below are the most typical patterns that I take advantage of to create good layouts. 😉

Set mounted with or peak

First one is the most straightforward one: set a view’s peak or a width to a set level.

testView.widthAnchor.constraint(equalToConstant: 320),
testView.heightAnchor.constraint(equalToConstant: 240),

Set facet ratio

Settings a view’s facet ratio is simply constrainting the width to the peak or vica versa, you’ll be able to merely outline the speed by the multiplier.

testView.widthAnchor.constraint(equalToConstant: 64),
testView.widthAnchor.constraint(equalTo: testView.heightAnchor, multiplier: 16/9),

Middle horizontally & vertically

Centering views inside one other one is a trivial process, there are particular anchors for that.

testView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
testView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),

Stretch | fill inside view with padding

The one tough half right here is that trailing and backside constraints behave somewhat bit totally different, than high & main if it involves the constants. Often you must work with detrimental values, however after a number of tries you will perceive the logic right here. 😅

testView.topAnchor.constraint(equalTo: self.view.topAnchor, fixed: 32),
testView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, fixed: 32),
testView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, fixed: -32),
testView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, fixed: -32),

Proportional width or peak

In case you do not wish to work with fixed values, you should use the multiplier.

testView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 1/3),
testView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 2/3),

Utilizing secure space format guides

With the newest iPhone you will want some guides to be able to hold you secure from the notch. That is the rationale why views have the safeAreaLayoutGuide property. You will get all the standard anchors after calling out to the secure space information. 💪

testView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
testView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
testView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
testView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),

Animating format constraints

Animation with constraints is simple, you should not consider what others may say. I made some guidelines and an instance that’ll provide help to understanding the essential ideas of animating fixed values of a constraint, plus toggling varied constraints. 👍

Guidelines:

  • Use commonplace UIView animation with layoutIfNeeded
  • All the time deactivate constraints first
  • Maintain to your deactivated constraints strongly
  • Have enjoyable! 😛

Constraint animation instance:

class ViewController: UIViewController {

    weak var testView: UIView!
    weak var topConstraint: NSLayoutConstraint!
    var bottomConstraint: NSLayoutConstraint!
    var heightConstraint: NSLayoutConstraint!

    override func loadView() {
        tremendous.loadView()

        let testView = UIView(body: .zero)
        testView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(testView)

        let topConstraint = testView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor)
        let bottomConstraint = testView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor)

        NSLayoutConstraint.activate([
            topConstraint,
            testView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
            testView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
            bottomConstraint,
        ])

        let heightConstraint = testView.heightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.heightAnchor, multiplier: 0.5)

        self.testView = testView
        self.topConstraint = topConstraint
        self.bottomConstraint = bottomConstraint
        self.heightConstraint = heightConstraint
    }

    override func viewDidLoad() {
        tremendous.viewDidLoad()

        self.testView.backgroundColor = .crimson

        let faucet = UITapGestureRecognizer(goal: self, motion: #selector(self.tapped))
        self.view.addGestureRecognizer(faucet)
    }

    @objc func tapped() {
        if self.topConstraint.fixed != 0 {
            self.topConstraint.fixed = 0
        }
        else {
            self.topConstraint.fixed = 64
        }

        if self.bottomConstraint.isActive {
            NSLayoutConstraint.deactivate([self.bottomConstraint])
            NSLayoutConstraint.activate([self.heightConstraint])

        }
        else {
            NSLayoutConstraint.deactivate([self.heightConstraint])
            NSLayoutConstraint.activate([self.bottomConstraint])
        }

        UIView.animate(withDuration: 0.25) {
            self.view.layoutIfNeeded()
        }
    }
}

It isn’t that dangerous, subsequent: adaptivity and supporting a number of machine display sizes. 🤔


The right way to create adaptive layouts for iOS?

Even Apple is scuffling with adaptive layouts within the built-in iOS functions. In case you take a look at apps which are made with assortment views – like images – layouts are fairly okay on each machine. Nonetheless there are a number of different ones, that – in my view – are horrible experiences on a much bigger display. #justusecollectionviewforeverything. 🤐

Rotation help

Your first step to adaptive format is supporting a number of machine orientations. You possibly can examine my earlier article about iOS auto format there are many nice stuff inside that article about rotation help, working with layers inside auto format land, and many others. 🌈

Trait collections

Second step is to adapt trait collections. UITraitCollection is there so that you can group all of the environmental particular traits corresponding to measurement courses, show scale, consumer interface idom and lots of extra. Many of the occasions you’ll have to examine the vertical & horizontal measurement courses. There’s a reference of machine measurement courses and all of the attainable variations made by Apple, see the exterior sources part beneath. 😉

This little Swift code instance beneath is demonstrating tips on how to examine measurement courses for setting totally different layouts for compact and common screens.

class ViewController: UIViewController {

    weak var testView: UIView!

    var regularConstraints: [NSLayoutConstraint] = []
    var compactConstraints: [NSLayoutConstraint] = []

    override func loadView() {
        tremendous.loadView()

        let testView = UIView(body: .zero)
        testView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(testView)

        self.regularConstraints = [
            testView.widthAnchor.constraint(equalToConstant: 64),
            testView.widthAnchor.constraint(equalTo: testView.heightAnchor),
            testView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            testView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
        ]

        self.compactConstraints = [
            testView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
            testView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
            testView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
            testView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
        ]

        self.activateCurrentConstraints()

        self.testView = testView
    }

    non-public func activateCurrentConstraints() {
        NSLayoutConstraint.deactivate(self.compactConstraints + self.regularConstraints)

        if self.traitCollection.verticalSizeClass == .common {
            NSLayoutConstraint.activate(self.regularConstraints)
        }
        else {
            NSLayoutConstraint.activate(self.compactConstraints)
        }
    }

    override func viewDidLoad() {
        tremendous.viewDidLoad()

        self.testView.backgroundColor = .crimson
    }

    

    override var shouldAutorotate: Bool {
        return true
    }

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .allButUpsideDown
    }

    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .portrait
    }

    

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        tremendous.traitCollectionDidChange(previousTraitCollection)

        self.activateCurrentConstraints()
    }
}

Gadget detection

You too can examine the consumer interface idom by the UIDevice class (aka. is that this freakin’ machine an iPhone or an iPad?) to set for instance font sizes based mostly on it. 📱

UIDevice.present.userInterfaceIdiom == .pad

Display measurement

Another choice to determine your surroundings is checking the measurement of the display. You possibly can examine the native pixel depend or a relative measurement based mostly in factors.


UIScreen.principal.nativeBounds   
UIScreen.principal.bounds         

Often I am making an attempt to maintain myself to those guidelines. I do not actually bear in mind a state of affairs the place I wanted greater than all of the issues I’ve listed above, however when you’ve got a particular case or questions, please do not hesitate to contact me. 😉



[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments