要查看一个非常基本的运行示例,请查看示例应用。首先克隆仓库,并在项目目录中运行 pod install
。
AutoLayoutKit 区分两种类型的约束
相关约束 指定一个与不同视图有关系的视图约束。例如,“按钮的宽度是其父视图宽度的 80%” 是一个 相关 约束:该约束指定按钮的宽度与按钮的父视图的宽度有关。
不相关约束 是只处理它们所属视图的约束。所有这些都涉及常数的使用。“按钮的高度是 44 像素” 是一个 不相关 约束:它指定按钮的高度独立于任何其他视图。
AutoLayoutKit 尝试提供一种 DSL,使您能够使用比 NSLayoutConstraint 的原始 API 更紧凑的、更自然语言的方式创建布局约束。
典型的布局创建如下所示
[ALKConstraints layout:self.optionA do:^(ALKConstraints *c) {
[c set:ALKHeight to:60.f name:kLKHeight];
[c set:ALKWidth to:60.f name:kLKWidth];
[c make:ALKRight equalTo:self.optionB s:ALKLeft plus:-10.f];
[c make:ALKCenterY equalTo:self s:ALKCenterY];
}];
此代码为您做了以下几件事
self.optionA
上创建一个 不相关 约束,将其 width
设置为 60 像素self.optionA
上创建一个 不相关 约束,将其 height
设置为 60 像素self
上创建一个 相关 约束,将 self.optionA
的右侧与 self.optionB
的左侧减去 10 像素对齐(以便在两个按钮之间创建 10 像素的边距)self
上创建一个 相关 约束,使按钮垂直居中非常得体,不是吗?实际上,AutoLayoutKit 还做得更多:它将这两个不相关约束命名为 kLKHeight
和 kLKWidth
,这样您就可以在运行时对这些约束进行修改。
但在我们讨论修改约束之前,先看看基本功能。为视图创建约束的语法如下
[ALKConstraints layout:<the receiver> do:^(ALKConstraints *c) {
<constraints specification>
}];
到目前为止没有什么神奇之处。这个 接收器 是受约束影响的视图。然而,这并不总是约束添加到的视图。您将看到如何在下一节中指定目标视图(添加约束的视图)。
在指定块中指定约束有两个API:`set` 和 `make`。您可能已经注意到,`set` 创建的是无关的约束,而 `make` 创建的是相关的约束。
使用 `set` 您可以直接在视图上设置布局属性,而使用 `make` 可以使用 `make` 将接收视图的布局属性视为其他视图的属性。
`set` 的(主要)API 是:
[c set:<layout attribute> to:<constant> name:<name>];
`make` 的(主要)API 是:
[c make:<layout attribute> equalTo:<related view> s:<related views layout attribute> plus:<constant>];
同时为 `set` 和 `make` 提供了一些不需要名称的API。此外,如第一个示例中所示,还有一个不需要常量的 `make` API。我已尽力使其尽可能方便。还有许多其他方便的方法,默认使用最常用的值。只需查看头文件即可。
从版本 0.5.0 开始,ALK 支持UILayoutPriorities。默认情况下,ALK创建的所有约束都使用 `UILayoutPriorityRequired` 优先级。您可以通过指定不同的优先级来更改此优先级,在进行任何约束之前。
[ALKConstraints layout:self.optionA do:^(ALKConstraints *c) {
[c set:ALKHeight to:60.f name:kLKHeight]; // priority == 1000 (required)
[c setPriority:500]; // set the priority to 500
[c set:ALKWidth to:60.f name:kLKWidth]; // priority == 500
[c make:ALKRight equalTo:self.optionB s:ALKLeft plus:-10.f]; // priority == 500
[c setPriorityRequired]; // reset to default
[c make:ALKCenterY equalTo:self s:ALKCenterY]; // priority == 1000 (required)
}];
当优先级由五种优先级方法之一设置时,更改将对此后创建的所有约束产生影响,直到指定了不同的优先级。
这五种方法分别是:
- (void)setPriority:(UILayoutPriority)priority;
- (void)setPriorityRequired; // 1000
- (void)setPriorityDefaultHigh; // 750
- (void)setPriorityDefaultLow; // 250
- (void)setPriorityFittingSizeLevel; // 50
有时,当您实际上是想要使用正常数时,需要指定负常数来指定约束。这常常会导致误解和丑陋的代码,如 `(-1) * myConst`。这种情况的一个好例子是子视图与它的父视图之间的底部边距。
假设您 want to 创建一个10像素的底部边距。您不需要写:
[ALKConstraints layout:childView do:^(ALKConstraints *c) {
[c make:ALKBottom equalTo:parentView s:ALKButton plus:((-1)*10.f)];
}];
您可以写
[ALKConstraints layout:childView do:^(ALKConstraints *c) {
[c make:ALKBottom equalTo:parentView s:ALKButton minus:10.f];
}];
这会做同样的事情,但更容易阅读。每个带有 `plus:` 的 API 都有一个对应的 `minus:`。
我们很少能够修改现有的 NSLayoutConstraint 实例,而我们唯一可以修改的是所谓的 constant 属性。我不知道苹果在给这个属性命名时是否意识到这一点是多么有趣。
通常,在处理稍后要修改的约束时,您需要始终保留对这些约束的引用。使用 AutoLayoutKit,您可以直接忘记这些约束,因为如果告诉它如何在未来引用特定的约束,它会跟踪这些约束。所有带有名称(这是可选的)的约束都可以通过以下 API 在任何时间从目标视图检索:
[someView alk_constraintWithName:<some name>];
类似地,这些约束可以通过调用以下API从目标视图中删除:
[someView alk_removeConstraintWithName:<some name>];
通过 constraintWithName: 检索到的约束可以按以下方式进行修改:
NSLayoutConstraint *height = [button alk_constraintWithName:kLKHeight];
height.constant = 70.f;
[button setNeedsUpdateConstraints];
第一行检索约束并将其存储在 height 中。第二行修改约束的 constant,最后一行标记按钮(目标视图)需要更新其约束。
注意,这些更改在此行之后不会生效。它们会在调用最近的一个祖先视图上的 `layoutIfNeeded` 之后生效。这可以在动画块内完成,然后动画将从最后一个(当前)约束设置转换到更改后的设置。
由于你通常一次会更改多个约束条件,因此AutoLayoutKit无法透明地执行此调用。你知道,当所有(同时)更改完成后,所有受影响的视图都会标记为更新。你知道,更改是否应通过动画立即应用。
AutoLayoutKit通过CocoaPods提供,要安装它,只需将以下行添加到您的Podfile中
pod "AutoLayoutKit"
Florian Krueger,[email protected]
AutoLayoutKit可在MIT许可证下使用。有关更多信息,请参阅LICENSE文件。