Set AutoLayout Size Class Programmatically?

前端 未结 3 1324
无人共我
无人共我 2020-12-28 19:25

With iOS 8 and Xcode 6, in storyboards we now have the screen size grid letting us select a size class. Where you can select layout formatting for the different screen sizes

相关标签:
3条回答
  • 2020-12-28 19:39

    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."

    0 讨论(0)
  • 2020-12-28 19:43

    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.

    0 讨论(0)
  • 2020-12-28 19:52

    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
    0 讨论(0)
提交回复
热议问题