以编程方式为不同大小类创建具有不同常量的自动布局约束

时间:2015-07-11 22:30:31

标签: ios nslayoutconstraint

如果使用Storyboard,则可以使用Interface Builder将自动布局约束添加到视图中,并且可以非常轻松地为所需的每个大小类添加不同的constant值。当您运行应用程序并在大小类之间切换时,UI将自动更新并重新定位以尊重新大小类的正确constant值。

我的问题是如何以编程方式获得相同的行为?

创建NSLayoutConstraint时,无法为不同的大小类设置不同的值。因此,我认为这将是一个更加手动的过程。您必须使用viewDidLoad中当前大小类的正确值创建约束,然后您必须使用willTransitionToTraitCollectionupdateConstraints并检测新大小class,然后针对适用于新大小类的所有约束更改constant,然后在需要重新定位的视图上调用layoutIfNeeded。这将是很多代码,更糟糕的是你优化的更大的类。有没有更简单和/或更有效的方式来以编程方式获得该行为?

请注意,此问题不仅限于自动布局约束,而是任何可以使其属性值根据大小类更改的对象。例如,为不同的大小类设置UILabel的字体。

1 个答案:

答案 0 :(得分:1)

夫特

您需要创建不同的NSLayoutConstraint

根据下面的讨论进行编辑。

  • @Joey:您必须同时处理viewDidLoad(或类似)和viewWillTransitionToSize中的尺寸类决定。

  • 尺寸等级检测应在animateAlongsideTransition块内完成,而不是之前。

重构代码:

override func viewDidLoad() {
    super.viewDidLoad()
    let narrow = self.view.traitCollection.horizontalSizeClass 
                 == UIUserInterfaceSizeClass.Compact
    self.useNarrowConstraints(narrow)
}


override func viewWillTransitionToSize(size: CGSize,
                                       withTransitionCoordinator
                                       coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    coordinator.animateAlongsideTransition({
        (UIViewControllerTransitionCoordinatorContext) -> Void in
            let narrow = self.view.traitCollection.horizontalSizeClass 
                         == UIUserInterfaceSizeClass.Compact
            self.useNarrowConstraints(narrow)
        })
        { (UIViewControllerTransitionCoordinatorContext) -> Void in 
        }
}

使用激活:

func useNarrowConstraints(narrow: Bool) {
    if narrow {
        NSLayoutConstraint.deactivateConstraints([self.fullWidthConstraint])
        NSLayoutConstraint.activateConstraints([self.halfWidthConstraint])
    } else {
        NSLayoutConstraint.deactivateConstraints([self.halfWidthConstraint])
        NSLayoutConstraint.activateConstraints([self.fullWidthConstraint])
    }
}

进一步详情here

使用替换

func useNarrowConstraints(narrow: Bool) {
    view.removeConstraint(constraint)

    if narrow {
        constraint = NSLayoutConstraint.constraintsWithVisualFormat("format", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
    } else {
        constraint = NSLayoutConstraint.constraintsWithVisualFormat("otherFormat", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
    }
    view.addConstraint(constraint)
}