以编程方式设置 AutoLayout 大小类?

Posted

技术标签:

【中文标题】以编程方式设置 AutoLayout 大小类?【英文标题】:Set AutoLayout Size Class Programmatically? 【发布时间】:2014-10-14 14:15:31 【问题描述】:

ios 8 和 Xcode 6 中,我们现在在情节提要中拥有屏幕尺寸网格,让我们可以选择尺寸等级。您可以在其中为不同的屏幕尺寸选择布局格式。

我发现这非常有用,因为它允许我设置基本约束,然后为每个屏幕尺寸设置唯一的约束。

我的问题是,您能以编程方式执行此操作吗?我照常创建NSLayoutConstraint,但我需要能够为不同的屏幕尺寸指定不同的约束。

【问题讨论】:

它们被称为尺寸类。 谢谢,不知道我是怎么错过的!现在,如果只有一种方法可以使用 NSLayoutConstraint 或类似的方式以编程方式指定大小类。 【参考方案1】:

iOS 8 在NSLayoutConstraint 上引入了active 属性。它允许您激活或停用约束。还有一些方法可以激活/停用多个约束。

+ (void)activateConstraints:(NSArray *)constraints
+ (void)deactivateConstraints:(NSArray *)constraints
以编程方式创建约束时,将它们保存在数组中。 为您需要的每个布局创建一个数组。 从willTransitionToTraitCollection 中激活/停用您需要的任何约束集

【讨论】:

谢谢,但也许在 2017 年还有其他方法吗?【参考方案2】:

要回答您的问题,您可以通过编程方式设置尺寸等级,但是这有点麻烦。您必须从父视图控制器调用“setOverrideTraitCollection”,而不是您真正希望对其进行特征更改的控制器。

在我的情况下,我想将 iPad 上的拆分视图控制器的 Master VC 更改为与 iPhone 上的不同,但是,默认情况下它们都设置为紧凑宽度/常规高度。因此,我将 Master 的导航控制器子类化并添加了代码,以便在 Master 不是 iPhone 时将 Master 的特征设置为常规宽度。

Swift 代码:

class MasterNavigationController: UINavigationController 

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

 

我希望这对寻找类似解决方案的人有所帮助。

【讨论】:

您手动设置了尺寸等级,但如何处理先前声明的约束?如何正确检测它们属于哪个特征? 在情节提要中为每个尺寸等级设置了约束(使用底部的设备图标)。这是来自 WWDC 2016 的视频,他们介绍了最近的变化。 developer.apple.com/videos/play/wwdc2016/236 我知道故事板,但问题是关于以编程方式声明的约束【参考方案3】:

这有点令人困惑且很难在文档中找到,因为“大小类”实际上并不是像 NSObject 那样的“类”。它们实际上是在枚举/typedef 中定义的:UIUserInterfaceSizeClass

获取视图的水平和垂直大小类的方法是使用UITraitCollection

UITraitCollection 的类/类型方法允许您根据特定的显示比例(例如是否视网膜)、从一组其他特征集合、使用 UI 习惯用法 (iPad/iPhone) 或特定的水平和垂直来创建一个选项(紧凑,常规),但老实说,我还不确定你会如何使用它......

This question 讨论了在 traitCollection 更改时更新约束,使用 willTransitionToTraitCollection(newCollection: UITraitCollection!, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator!)

您说得对,UITraitCollection 及其属性都是只读的,但显然您可以出于某种原因创建一个新集合,并在 traitCollection 更改时处理布局更改。

This previous question 非常相似,并链接到 Apple 关于使用自适应布局的文章。另请查看 WWDC 视频“使用 UIKit 构建自适应应用程序”。

【讨论】:

我明天应该有时间看 WWDC 视频。但是,您不能设置视图或布局约束的 traitCollection 属性,只能读取。那么如何应用约束来属于某个特征集合呢?他们带来了一个有趣的变化,到目前为止我很喜欢它。 找到并添加了有关更改约束的相关问题。显然有一些方法可以创建新的 UITraitCollections,并在查看 willTransitionToTraitCollection 时将它们传递给方法......但几个月来我还没有玩够它或观看视频。是时候让我再看看了!对我来说,自适应布局的流程和文档非常糟糕而且令人困惑,因为它是一个如此大的新功能......最终会弄明白的!

以上是关于以编程方式设置 AutoLayout 大小类?的主要内容,如果未能解决你的问题,请参考以下文章

使用 UIScrollView 和 AutoLayout 以编程方式创建控制器无法正确调整视图大小

如何以编程方式设置 UIScrollView 以使用 autoLayout 水平滚动

如何防止 UIImageView 使用 Autolayout 调整大小

以编程方式更改故事板上的 UIView 的大小

如何使用水平滚动以编程方式执行 AutoLayout?

使用 AutoLayout 以编程方式将 UILabel 添加到 ScrollView (swift)