Set AutoLayout Size Class Programmatically?

萝らか妹 提交于 2019-11-30 03:38:53

iOS 8 introduces the active property on NSLayoutConstraint. It allows you to activate or deactivate a constraint. There are also methods to activate/deactivate multiple constraints.

+ (void)activateConstraints:(NSArray *)constraints
+ (void)deactivateConstraints:(NSArray *)constraints
  • Keep your constraints in arrays when creating them programmatically.
  • Create an array for each of the layouts you need.
  • Activate/Deactivate whatever set of constraints you need from within willTransitionToTraitCollection

To answer your question, you can set the size class programmatically, however, it's a bit of a pain. You must call "setOverrideTraitCollection" but from the parent view controller, not the one you actually wished to make a trait change to.

In my situation, I wanted to change the Master VC of a split view controller on iPad to look differently than the one on the iPhone, however, they are both set to Compact width / Regular height by default. So I subclassed the Master's nav controller and added code to set the Master's traits to Regular width when it's not an iPhone.

Swift code:

class MasterNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        if (self.traitCollection.userInterfaceIdiom != .Phone) {
            let newTraitCollection = UITraitCollection(horizontalSizeClass: .Regular)
            self.setOverrideTraitCollection(newTraitCollection, forChildViewController: self.topViewController)
        }
    }

} 

I hope this helps someone looking for a similar solution.

mc01

It's a bit confusing & hard to find in the documentation because a "size class" isn't actually a "Class" like NSObject. They're really defined in an enum/typedef called: UIUserInterfaceSizeClass

The way to get the horizontal & vertical size class for a view is with a UITraitCollection

Class/Type methods for UITraitCollection allow you to create one based on a particular display scale (e.g. retina or not), from an array of other trait collections, with a UI idiom (iPad/iPhone), or specific horizontal & vertical options (compact, regular), but to be honest I'm not sure yet how you'd use this...

This question discusses updating constraints when the traitCollection changes, using willTransitionToTraitCollection(newCollection: UITraitCollection!, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator!)

You're right that both the UITraitCollection and its properties are readonly, but clearly you can create a new collection for some reason, and handle layout changes when the traitCollection changes.

This previous question is pretty similar & links to an Apple article about using Adaptive Layout. Also check the WWDC video "Building Adaptive Apps with UIKit."

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!