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

14

在iOS 8和Xcode 6中,我们现在可以通过故事板选择屏幕尺寸网格来选择大小类,以便为不同的屏幕尺寸选择布局格式。

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

我的问题是,是否可以通过编程实现这一点?我像平常一样创建我的NSLayoutConstraint,但我需要能够为不同的屏幕尺寸指定不同的约束。


2
它们被称为大小类。 - rckoenes
谢谢,不确定我是怎么错过那个的!现在如果只有一种方法可以使用NSLayoutConstraint或类似的方式编程指定大小类的话就好了。 - Josh Kahane
3个回答

14

iOS 8 引入了 active 属性到 NSLayoutConstraint 上。它允许你激活或取消一个约束条件。同时还有方法可以批量激活/取消多个约束条件。

+ (void)activateConstraints:(NSArray *)constraints
+ (void)deactivateConstraints:(NSArray *)constraints
  • 在以编程方式创建约束时,将约束存储在数组中。
  • 为所需的每个布局创建一个数组。
  • willTransitionToTraitCollection中激活/停用所需的约束集。

谢谢,但也许在2017年有其他方法? - Vyachaslav Gerchicov

1

这可能有些令人困惑并且在文档中很难找到,因为“size class”实际上不像NSObject一样是一个“Class”。它们真正被定义在一个枚举/typedef中,叫做:UIUserInterfaceSizeClass

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

UITraitCollection的类/类型方法允许您基于特定的显示比例(例如retina或非retina)、从其他trait collection数组、使用UI风格(iPad/iPhone)或特定的水平和垂直选项(紧凑、常规)创建一个trait collection,但老实说我还不确定如何使用它...

这个问题讨论了在traitCollection更改时使用willTransitionToTraitCollection(newCollection: UITraitCollection!, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator!)更新约束的方法。

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

这个之前的问题非常类似,并链接到了一个关于使用自适应布局的苹果文章。还要查看WWDC视频“使用UIKit构建自适应应用程序”。


明天我应该有时间观看WWDC视频。然而,您无法设置视图或布局约束的traitCollection属性,只能读取。那么,如何将约束应用于属于特定trait集合?这是一个有趣的变化,我到目前为止相当喜欢它。 - Josh Kahane
发现并添加了一个关于更改约束的相关问题。显然有方法可以创建新的UITraitCollections,并在视图“willTransitionToTraitCollection”时将它们传递给方法...但我还没有玩够或观看视频已经几个月了。是时候再次看一眼了!对我来说,自适应布局的过程和文档非常糟糕和令人困惑,考虑到它是一个如此重要的新功能...最终会弄清楚的! - mc01

1
为了回答你的问题,你可以通过编程设置大小类,但是这有点麻烦。你必须调用 "setOverrideTraitCollection",但是从父视图控制器中调用,而不是你实际希望改变特质的那个视图控制器。
在我的情况下,我想要将iPad上的分割视图控制器的Master VC与iPhone上的不同,然而它们默认都设置为紧凑宽度/常规高度。所以我子类化了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)
        }
    }

} 

我希望这可以帮助寻找类似解决方案的人。

你手动设置了尺寸类别,但之前声明的约束条件该怎么办?如何正确地检测它们所属的特征? - Vyachaslav Gerchicov
在Storyboard中为每个尺寸类别设置了约束(使用底部的设备图标)。这是WWDC 2016的一个视频,其中详细介绍了最近的更改。https://developer.apple.com/videos/play/wwdc2016/236/ - Travis M.
1
我知道故事板,但问题是关于以编程方式声明约束。 - Vyachaslav Gerchicov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接