如何以编程方式创建布局约束
最近在开发 iOS 应用时,遇到了一个问题:如何通过编程方式创建布局约束。在研究了一些资料后,我找到了解决方法。
自从 iOS 9 以来,使用锚点可以非常简单地完成这项任务。下面是 Swift 3 中的示例代码:
extension UIView {
func addConstaintsToSuperview(leadingOffset: CGFloat, topOffset: CGFloat) {
guard superview != nil else {
return
}
translatesAutoresizingMaskIntoConstraints = false
leadingAnchor.constraint(equalTo: superview!.leadingAnchor,
constant: leadingOffset).isActive = true
topAnchor.constraint(equalTo: superview!.topAnchor,
constant: topOffset).isActive = true
}
func addConstaints(height: CGFloat, width: CGFloat) {
heightAnchor.constraint(equalToConstant: height).isActive = true
widthAnchor.constraint(equalToConstant: width).isActive = true
}
}
此外,如果你使用 Objective-C,你可以创建一个 category 来添加约束方法。下面是一个示例:
@interface UIView (Constraints) - (void)addConstaintsToSuperviewWithLeadingOffset:(CGFloat)leadingOffset topOffset:(CGFloat)topOffset; - (void)addConstaintsWithHeight:(CGFloat)height width:(CGFloat)width; @end @implementation UIView (Constraints) - (void)addConstaintsToSuperviewWithLeadingOffset:(CGFloat)leadingOffset topOffset:(CGFloat)topOffset { if (self.superview == nil) { return; } self.translatesAutoresizingMaskIntoConstraints = false; [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeLeading multiplier:1.0 constant:leadingOffset].active = YES; [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:topOffset].active = YES; } - (void)addConstaintsWithHeight:(CGFloat)height width:(CGFloat)width { [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:height].active = YES; [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:width].active = YES; } @end
通过以上的代码,我们可以在编程中轻松地创建布局约束。希望这篇文章对你理解如何通过编程方式创建布局约束有所帮助。
如何通过编程方式创建布局约束
在上面的代码中,我们提供了一种使用程序编写布局约束的方法。这是因为在未来版本中,addConstraint方法将被弃用。为了解决这个问题,我们提供了一个UIView的扩展,以便在将视图添加到层次结构之后使用这些函数。
在Objective-C中,我们提供了两个函数:addConstaintsToSuperviewWithLeftOffset和addConstaintsWithWidth。addConstaintsToSuperviewWithLeftOffset函数用于将视图添加到其父视图的左侧和顶部,并指定偏移量。addConstaintsWithWidth函数用于指定视图的宽度和高度。
在Swift 3中,我们提供了两个类似的函数:addConstaintsToSuperview和addConstaints。这两个函数的功能与Objective-C版本中的函数相同,只是语法稍有不同。
通过使用这些函数,我们可以通过编程方式创建布局约束,而不需要使用addConstraint方法。这样可以确保我们的代码在将来的版本中仍然能够正常工作,并且与最新的API保持兼容。
这些函数的使用非常简单,只需将视图添加到层次结构中,然后调用适当的函数来添加约束即可。这样,我们就可以通过编程方式创建布局约束,而不需要手动添加约束。
希望这些函数对于通过编程方式创建布局约束的开发者来说是有用的。通过使用这些函数,我们可以更轻松地管理视图的布局,并确保我们的代码在不同的设备和屏幕尺寸上都能正常工作。
如何以编程方式创建布局约束?
要将视图固定在屏幕底部,需要设置以下约束:
1. 使用父视图设置相对于X轴的前导约束。
2. 使用父视图设置相对于宽度的尾随约束。
3. 使用父视图设置相对于Y轴的底部约束。
4. 将高度约束附加到自身。
代码示例:
UIView *subView = bottomView; UIView *parent = self.view; subView.translatesAutoresizingMaskIntoConstraints = NO; // Trailing NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:parent attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:0.f]; // Leading NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:parent attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.f]; // Bottom NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:parent attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.f]; // Height NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:ADHeight]; // Add constraints to the parent [parent addConstraint:trailing]; [parent addConstraint:bottom]; [parent addConstraint:leading]; // Add height constraint to the subview [subView addConstraint:height];
`height`中的`attribute`值实际上应该是`NSLayoutAttributeNotAnAttribute`,而不是`0`。
`NSLayoutAttributeNotAnAttribute`的值为0,它是枚举值,所以两者是相同的,没有区别,具体使用哪个取决于个人选择。
这个设置应该在`awakeFromNib`还是`viewDidLoad`中完成?为什么?
这个设置应该只添加一次,选择`viewDidLoad`,因为它只会被调用一次。
纠正我如果我错了:对于所有的约束,都有一个`constraintWithItem`和`toItem`属性。这意味着约束已经指定了它是在什么之间以及它们如何相互关联。我的问题是:当你调用`[parent addConstraint:trailing]`时,你是否可以使用`[subView addConstraint:trailing]`代替?
不可以使用子视图,因为尾随、前导、顶部和底部应该是相对于父视图添加的,而固定的宽度和高度应该是相对于子视图添加的。
你是不是指当调用`[someView addConstraint:aConstraint]`时,`NSLayoutAttributeLeading`或`NSLayoutAttributeTrailing`会根据`someView`而不是`toItem`的value来确定它们之间的关系?
我想让子视图的高度与父视图的高度相对应(例如父视图的1/3)。如何添加?
所有的约束都可以一次设置,例如`[self addConstraints:@[leading, trailing, bottom]]`。