ios - 以编程方式为不同尺寸类别创建具有不同常量的自动布局约束

标签 ios nslayoutconstraint

如果您使用 Storyboard,您可以使用 Interface Builder 向 View 添加自动布局约束,并且您可以非常轻松地为您想要的每个尺寸类别添加不同的 constant 值。当您运行应用程序并在尺码等级之间切换时,UI 将自动更新并重新定位以遵守新尺码等级的正确常量值。

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

当您创建一个 NSLayoutConstraint 时,您不能为不同的尺寸类别设置不同的值。因此,我认为这将是一个更加手动的过程。例如,您必须为 viewDidLoad 中的当前大小类创建具有正确值的约束,然后您必须使用 willTransitionToTraitCollection 或者 updateConstraints 并检测新的大小类,然后更改适合新​​大小类的所有约束的 constant,然后在 View 上调用 layoutIfNeeded需要重新定位。那将是很多代码,更糟糕的是您优化的大小类越多。有没有更简单和/或更有效的方法来以编程方式获得该行为?

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

最佳答案

swift

你需要创建不同的NSLayoutConstraint集合。

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

  • @Joey :您必须在 viewDidLoad(或类似的)和 viewWillTransitionToSize 中处理大小类决策。

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

重构代码:

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)
}

关于ios - 以编程方式为不同尺寸类别创建具有不同常量的自动布局约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31362471/

相关文章:

ios - 双击或使用按钮将相机从后切换到前(Xcode 8、Swift 3)

ios - 我应该如何正确映射代码为 200 的错误响应?

ios - UIScrollView 和约束问题

ios - 内切 View 的自动布局约束

ios - Firebase 给了我 Use of undeclared type with FIRDatabase and FIRDataSnapshot

ios - Swift Firebase 为 UIActivityViewController 附加图像

ios - 通过 iCarousel 将信息传递给多个 viewController

ios - Swift:无法使用 NSLayoutConstraint 在 Superview 中居中 UIView

ios - 标签不自动调整距离

ios - 动态更改由自动布局控制的 View 的纵横比