【问题标题】:How to set standard spacing between UIViews in code with auto layout?如何在具有自动布局的代码中设置 UIView 之间的标准间距?
【发布时间】:2012-10-10 10:03:17
【问题描述】:

在界面生成器中,我可以通过“固定”获得与“标准”间距匹配的“垂直空间”:

在视觉约束语言中,我可以完成同样的事情:

V:[top]-[bottom]

如何在代码中的两个视图之间添加标准间距?

我正在寻找可能出现在 UIViewController 中的类似内容:

NSLayoutConstraint *spacing = ???
[self.view addConstraint spacing];

【问题讨论】:

  • 你为什么不能在代码中使用视觉格式,或者这只是一个好奇的问题(这对我来说很好!)
  • @jrturton,我所有的其他约束都在代码中。我这样做是因为我在文档中找到了以下语句:“有些约束无法以可视格式语法表达,尽管在真实用户界面中有用的大多数约束都可以。一个无法表达的有用约束是一个固定的纵横比(例如,imageView.width = 2 * imageView.height)。“直到我知道我在做什么并且视觉语言的所有限制都变得清晰之前,我想先用代码做所有事情。

标签: ios autolayout


【解决方案1】:

从 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

【讨论】:

  • 不就是硬编码一个8的空格吗?我认为 OP 是在使用一些系统常量或关键字来描述标准间距。
  • @jrturton 我在头文件中找不到它的常量。
  • @jrturton,如果有一个表示标准间距的系统常数,那将是一个不错的选择。但我宁愿不直接使用数字 8。
  • @robmayoff 我也不能。说到自动布局,非常感谢您在stackoverflow.com/questions/12943107/… 上的意见,它似乎在您的几个专业框中打勾?
【解决方案2】:

混合和匹配视觉格式约束和更冗长的单一约束创建样式(我认为您在说“代码中”时指的是)很好 - 事实上,在 WWDC 讨论自动布局时,“首选" 你创建约束的顺序被表述为:

  • 界面构建器
  • 视觉格式
  • 单一约束样式

除非您需要单一约束样式为您提供的额外功能和灵活性(根据我迄今为止的经验,有很多地方视觉格式不起作用),您应该使用视觉格式。听起来您是从下往上而不是自上而下接近上面的列表。

如果您想以标准间距布置视图,并且您没有使用 IB,那么使用视觉格式是有意义的。正如 Rob 所说,没有可用的“标准”间距常量,并且通过坚持对所有内容都使用单一约束,您可以为自己做更多的工作。

【讨论】:

  • 我最终采用了混合视觉格式样式,但有一个例外 - 一种相对大小的约束,除了代码之外无法表达。这大大清理了约束代码。好电话。
【解决方案3】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多