有没有办法在故事板中更新大量约束的常量值?

时间:2016-06-24 23:39:53

标签: xcode storyboard xcode-storyboard

假设在我的故事板中,我有一堆控制器视图,它们的内容与左边缘和右边缘对齐,具有一定的插入(例如:填充为6pts)。如果我以后想要更改填充值,如何在整个项目中快速进行更改?有没有办法在Storyboard中使用某个标签更改所有约束的常量,或者我是否必须创建一种" contentView" class并将它放在我项目中每个ViewController的基本视图中?

2 个答案:

答案 0 :(得分:1)

如果子视图固定到的超级视图位于自动布局下,则在superview的“大小”检查器中,它具有“布局边距”部分。因此,如果将这些子视图固定到布局边距(在Interface Builder中创建约束时无论如何都是默认设置),您所要做的就是更改超视图的布局边距。

这很简单,但是没有神奇的方法可以在一个动作中为整个故事板中的所有超级视图执行此操作(除非您想要真正大胆并将故事板编辑为文本 - 毕竟它只是XML,毕竟)。

答案 1 :(得分:1)

您可以使用NSLayoutConstraint的自定义子类

获得所需的效果
class AdjustableConstraint: NSLayoutConstraint {

    @IBInspectable var name: String = ""

    class func setConstant(ofConstraintsNamed name: String, to value: CGFloat) {
        constantForName[name] = value
        NSNotificationCenter.defaultCenter().postNotificationName(notificationName,
            object: self, userInfo: [nameKey: name])
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: #selector(AdjustableConstraint.observeAdjustmentNotification(_:)),
            name: AdjustableConstraint.notificationName, object: AdjustableConstraint.self)

        updateConstant()
    }

    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self,
            name: AdjustableConstraint.notificationName, object: AdjustableConstraint.self)
    }

    @objc private func observeAdjustmentNotification(note: NSNotification) {
        guard
            let userInfo = note.userInfo
            where userInfo[AdjustableConstraint.nameKey] as? String == name
        else { return }

        updateConstant()
    }

    private func updateConstant() {
        if let newConstant = AdjustableConstraint.constantForName[name] {
            self.constant = newConstant
        }
    }

    private static var constantForName = [String: CGFloat]()
    private static let notificationName = "UpdateAdjustableConstraintConstant"
    private static let nameKey = "name"


}

以下是如何使用它。对于要一起调整的故事板中的所有约束,请将其自定义类设置为AdjustableConstraint。 (您可以在文档大纲中选择多个约束来同时设置所有约束的自定义类。)

这样做会使Xcode在Attributes Inspector中为这些约束显示一个新字段“Name”。将名称设置为某些字符串,如“customMargin”:

attributes inspector with name field

在您的代码中,您可以使用特定名称设置每个AdjustableConstraint的常量:

AdjustableConstraint.setConstant(ofConstraintsNamed: "customMargin", to: 10)

从故事板加载AdjustableConstraint时,如果您之前为其名称设置了常量,则会应用该常量。所以这也适用于新加载的约束。您可能希望在加载任何约束之前初始化常量,方法是在启动时在应用程序委托中设置它:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    AdjustableConstraint.setConstant(ofConstraintsNamed: "customMargin", to: 30)
    return true
}