使用视觉格式语言(Visual Format Language)管理 Auto Layout 约束的轻量级工具。
假设你有一个视图,有一个子视图,就像这样
@interface MyView : UIView
@property (nonatomic, strong) UIView *mySubview;
@property (nonatomic, strong) AZConstraintsRegister *constraintsRegister;
@end
为了使用注册器,你需要做两件事情。首先,你需要注册容器视图及其子视图,这些视图将用于 AutoLayout。你可以在初始化器中这样做
- (id)initWithFrame:(CGRect)rect {
self = [super initWithFrame:rect];
if (self) {
self.subview = [UIView new];
[self addSubview:self.subview];
self.constraintsRegister = [AZConstraintsRegister registerWithContainerView:self];
[self.constraintsRegister registerSubview:self.subview forLayoutKey:@"subview"];
}
return self;
}
你还可以使用变量绑定宏来注册尺寸和子视图,检查 NSDictionaryOfVariableBindings 章节以了解注册器如何处理这些绑定。
现在你可以享受注册器的简洁性,只需在调用 beginUpdates
和 endUpdates
之间添加 VFL 约束即可
[self.constraintsRegister beginUpdates]; // clears previous state
[self.constraintsRegister registerFormat:@"|-[subview]-|"];
[self.constraintsRegister registerFormat:@"V:|-[subview]-|"];
[self.constraintsRegister endUpdates]; //submits created constraints to the view
为了更少的代码,你可以使用大量格式注册器
[self.constraintsRegister beginUpdates]; // clears previous state
[self.constraintsRegister registerFormats:@[
@"|-(left)-[subview]-(right)-|",
@"V:|-(top)-[subview]-(bottom)-|"
]];
[self.constraintsRegister endUpdates]; //submits created constraints to the view
你可以在初始化器中为静态约束执行一次,或者如果你想有更多的动态行为,在 updateConstraints
中执行
- (void)updateConstraints {
[self.constraintsRegister beginUpdates]; // clears previous state
[self.constraintsRegister registerFormat:@"|-[subview]-|"];
[self.constraintsRegister registerFormat:@"V:|-[subview]-|"];
[self.constraintsRegister endUpdates]; //submits created constraints to the view
[super updateConstraints];
}
在这种情况下,请记住在某个地方调用 setNeedsUpdateConstraints
,否则 updateConstraints
不会被触发。
还有很多其他功能!值得提到的是,简单的 AZConstraintsRegister
跟踪每个已注册的约束,因此它不会与现有的或外部添加的约束冲突。
关于注册器的酷点在于它可以使代码更清晰,你不需要使用这个长 NSLayoutConstraint
方法。
当创建 NSLayoutConstraint
时,你可以提供 metrics
字典,其中你可以指定命名值,稍后在 VFL 中引用。
NSDictionary *views = @{
@"subview" : self.subview
};
NSDictionary *metrics = @{
@"mySpacing" : @(20.0f)
};
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-(mySpacing)-[subview]-|"
options:0
metrics:metrics
views:views];
这很酷,但代码很长,不容易阅读。这时,AZConstraintsRegister
就能帮到你了!每当你需要为 VFL 注册一个尺寸时,你可以这样做
[self.constraintsRegister registerMetric:@(20.0f) forKey:@"mySpacing"];
或者
[self.constraintsRegister registerMetrics:@{
@"mySpacing" : @(20.0f)
}];
然后你可以在你的 VFL 中引用 mySpacing
。
默认情况下,AZConstraintsRegister
包含两个默认尺寸指标,这些指标作为属性公开。
@property(nonatomic) UIEdgeInsets contentInsets;
@property(nonatomic) CGFloat interItemSpacing;
这些是动态属性,在设置时会更新指标。这使得你能够轻松设置指标,并在你的 VFL 中使用预定义的指标键。
extern NSString *const AZConstraintRegisterTopKey; //based on contentInsets.top,
extern NSString *const AZConstraintRegisterLeftKey; //based on contentInsets.left,
extern NSString *const AZConstraintRegisterBottomKey; //based on contentInsets.bottom
extern NSString *const AZConstraintRegisterRightKey; //based on contentInsets.right
extern NSString *const AZConstraintRegisterSpacingKey; //based on interItemSpacing
例如
[self.constraintsRegister registerConstraintWithFormat:@"|-(left)-[subview]-(right)-|"];
[self.constraintsRegister registerConstraintWithFormat:@"V:|-(top)-[subview]-(bottom)-|"];
与Auto Layout一起,苹果推出了辅助宏NSDictionaryOfVariableBindings
,可以快速创建一个包含提供变量的字典。它运行良好,但当你以这种方式注册属性时会破坏VFL:
NSDictionary *bindings = NSDictionaryOfVariableBindings(self.subview)
在bindings
中对子视图的键将是self.subview
,如果在VFL中引用它将引发异常。为了使用这个酷宏并且能够与其属性一起使用,`AZConstraintsRegister`提供两个辅助方法:
- (void)registerSubviewsWithVariableBindings:(NSDictionary *)variableBindings;
- (void)registerMetricsWithVariableBindings:(NSDictionary *)metricsBindings;
它本质上从绑定字典中的键中剥离键路径,从而减少代码,并允许你做以下操作:
NSDictionary *bindings = NSDictionaryOfVariableBindings(self.subview);
[self.constraintsRegister registerSubviewsWithVariableBindings:bindings];
[self.constraintsRegister registerFormat:@"|-[subview]-|"]
要运行示例项目,请克隆仓库,然后首先从示例目录运行pod install
。
iOS SDK 6及更高版本(Auto Layout就是从这个版本引入的)
Aleksander Zubala,[email protected]
AZConstraintsRegister在MIT许可下可用。有关更多信息,请参阅LICENSE文件。