在界面生成器中,我可以通过“固定”获得与“标准”间距匹配的“垂直空间”:
在视觉约束语言中,我可以通过以下方式完成同样的事情:
V:[top]-[bottom]
如何在代码中的两个视图之间添加标准间距?
我正在寻找可能出现在 UIViewController 中的类似内容:
NSLayoutConstraint *spacing = ???
[self.view addConstraint spacing];
在界面生成器中,我可以通过“固定”获得与“标准”间距匹配的“垂直空间”:
在视觉约束语言中,我可以通过以下方式完成同样的事情:
V:[top]-[bottom]
如何在代码中的两个视图之间添加标准间距?
我正在寻找可能出现在 UIViewController 中的类似内容:
NSLayoutConstraint *spacing = ???
[self.view addConstraint spacing];
从 iOS 11.0(2017 年发布)开始,有一些使用系统间距的方法:
@interface NSLayoutXAxisAnchor (UIViewDynamicSystemSpacingSupport)
/* Constraints of the form,
receiver [= | ≥ | ≤] 'anchor' + 'multiplier' * system space,
where the value of the system space is determined from information available from the anchors.
The constraint affects how far the receiver will be positioned trailing 'anchor', per the effective user interface layout direction.
*/
- (NSLayoutConstraint *)constraintEqualToSystemSpacingAfterAnchor:(NSLayoutXAxisAnchor *)anchor multiplier:(CGFloat)multiplier __attribute__((warn_unused_result)) API_AVAILABLE(macos(11.0),ios(11.0),tvos(11.0));
- (NSLayoutConstraint *)constraintGreaterThanOrEqualToSystemSpacingAfterAnchor:(NSLayoutXAxisAnchor *)anchor multiplier:(CGFloat)multiplier __attribute__((warn_unused_result)) API_AVAILABLE(macos(11.0),ios(11.0),tvos(11.0));
- (NSLayoutConstraint *)constraintLessThanOrEqualToSystemSpacingAfterAnchor:(NSLayoutXAxisAnchor *)anchor multiplier:(CGFloat)multiplier __attribute__((warn_unused_result)) API_AVAILABLE(macos(11.0),ios(11.0),tvos(11.0));
@end
@interface NSLayoutYAxisAnchor (UIViewDynamicSystemSpacingSupport)
/* Constraints of the form,
receiver [= | ≥ | ≤] 'anchor' + 'multiplier' * system space,
where the value of the system space is determined from information available from the anchors.
The constraint affects how far the receiver will be positioned below 'anchor'.
If either the receiver or 'anchor' is the firstBaselineAnchor or lastBaselineAnchor of a view with text content
then the spacing will depend on the fonts involved and will change when those do.
*/
- (NSLayoutConstraint *)constraintEqualToSystemSpacingBelowAnchor:(NSLayoutYAxisAnchor *)anchor multiplier:(CGFloat)multiplier __attribute__((warn_unused_result)) API_AVAILABLE(macos(11.0),ios(11.0),tvos(11.0));
- (NSLayoutConstraint *)constraintGreaterThanOrEqualToSystemSpacingBelowAnchor:(NSLayoutYAxisAnchor *)anchor multiplier:(CGFloat)multiplier __attribute__((warn_unused_result)) API_AVAILABLE(macos(11.0),ios(11.0),tvos(11.0));
- (NSLayoutConstraint *)constraintLessThanOrEqualToSystemSpacingBelowAnchor:(NSLayoutYAxisAnchor *)anchor multiplier:(CGFloat)multiplier __attribute__((warn_unused_result)) API_AVAILABLE(macos(11.0),ios(11.0),tvos(11.0));
@end
在 Swift 中,你可以像这样使用它们:
let topView: UIView = ...
let bottomView: UIView = ...
bottomView.topAnchor
.constraint(equalToSystemSpacingBelow: topView.bottomAnchor, multiplier: 1)
.isActive = true
let leadingView: UIView = ...
let trailingView: UIView = ...
trailingView.leadingAnchor
.constraint(equalToSystemSpacingAfter: leadingView.trailingAnchor, multiplier: 1)
.isActive = true
混合和匹配视觉格式约束以及更冗长的单一约束创建样式(我认为您在说“代码中”时指的是)很好 - 事实上,在 WWDC 讨论自动布局时,“首选”顺序您创建约束的表述为:
除非您需要单一约束样式为您提供的额外功能和灵活性(并且有很多地方视觉格式不起作用,根据我迄今为止的经验),您应该使用视觉格式。听起来您是从下往上而不是自上而下接近上面的列表。
如果您想以标准间距布置视图,并且您没有使用 IB,那么使用视觉格式是有意义的。正如 Rob 所说,没有可用的“标准”间距常量,并且通过坚持对所有内容都使用单一约束,您可以为自己做更多的工作。
自发布此问题以来,已发布约束 API 以使用标准系统间距默认值:
constraint(equalToSystemSpacingAfter:multiplier:)
constraint(greaterThanOrEqualToSystemSpacingAfter:multiplier:)
constraint(lessThanOrEqualToSystemSpacingAfter:multiplier:)
Apple 提供了使用此功能的示例代码,即Creating Self-Sizing Table View Cells。