自定义 UITableViewCell 是否有一种简单的方法可以与标准 UITableViewCell 具有相同的边缘?
Is there a simple way how a custom UITableViewCell can have the same edges as a standard UITableViewCell?
我有一个带有静态内容的自定义 UITableViewCell,它有一个 UIStackView 作为内容视图的单个子视图。我希望 UIStackView 使用与 UIKit 内置的标准 UITableViewCell 相同的水平 margins/insets,跨所有 iOS 版本,从 iOS 9(我的最小部署目标)开始到当前 iOS 14,并且在 iPhone 和 iPad 设备上。
我天真地开始添加约束,将 UIStackView 的 leading/trailing 锚点附加到内容视图的 readableContentGuide
。我不喜欢 Interface Builder,所以我的代码是这样的:
UIStackView stackView = [...]
[stackView.leadingAnchor constraintEqualToAnchor:self.contentView.readableContentGuide.leadingAnchor].active = YES;
[stackView.trailingAnchor constraintEqualToAnchor:self.contentView.readableContentGuide.trailingAnchor].active = YES;
这工作得很好,除了在某些情况下 (1) 标准 UITableViewCell 不 使用 readableContentGuide
,所以将标准单元格与我的自定义单元格混合看起来不好,因为它们的边缘没有对齐。此处您看到 4 个自定义单元格,顶部和底部各有一个标准单元格:
(1) 它发生在这些场景中:
- 在 iPhone 有槽口的设备上,当设备横向放置时
- 在 iPad 设备上,纵向和横向均如此
我曾尝试使用 layoutMarginsGuide
而不是 readableContentGuide
,但这会导致许多约束错误(“无法同时满足约束。”在 Xcode 的调试输出中)。我也试过设置
self.tableView.cellLayoutMarginsFollowReadableWidth = YES;
在 table 视图中使用我的自定义单元格,这是有效的,因为标准单元格现在的边缘与我的自定义单元格位于同一位置。但我不喜欢这种解决方法,首先是因为这意味着我必须为每个想要使用我的自定义单元格的 table 视图进行特殊设置,其次是因为它不必要地减少了可用于数据显示的宽度.
我好像漏掉了什么。是否有一种简单、标准的方法可以如何使用布局指南来布局自定义 UITableViewCell 的内容,以便自定义单元格内容的边缘与标准单元格的边缘位于同一位置?
您应该可以使用单元格的 .contentView.layoutMarginsGuide
:
UILayoutGuide *g = self.contentView.layoutMarginsGuide;
[NSLayoutConstraint activateConstraints:@[
[stackView.topAnchor constraintEqualToAnchor:g.topAnchor],
[stackView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor],
[stackView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor],
[stackView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor],
]];
如果这给你“无法同时满足约束”的消息,但布局看起来正确——这在单元格中使用堆栈视图时很常见——你可以忽略这些消息或给予底部锚点低于要求的优先级:
UILayoutGuide *g = self.contentView.layoutMarginsGuide;
NSLayoutConstraint *c = [stackView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor];
c.priority = UILayoutPriorityDefaultHigh;
[NSLayoutConstraint activateConstraints:@[
[stackView.topAnchor constraintEqualToAnchor:g.topAnchor],
[stackView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor],
[stackView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor],
c,
]];
我有一个带有静态内容的自定义 UITableViewCell,它有一个 UIStackView 作为内容视图的单个子视图。我希望 UIStackView 使用与 UIKit 内置的标准 UITableViewCell 相同的水平 margins/insets,跨所有 iOS 版本,从 iOS 9(我的最小部署目标)开始到当前 iOS 14,并且在 iPhone 和 iPad 设备上。
我天真地开始添加约束,将 UIStackView 的 leading/trailing 锚点附加到内容视图的 readableContentGuide
。我不喜欢 Interface Builder,所以我的代码是这样的:
UIStackView stackView = [...]
[stackView.leadingAnchor constraintEqualToAnchor:self.contentView.readableContentGuide.leadingAnchor].active = YES;
[stackView.trailingAnchor constraintEqualToAnchor:self.contentView.readableContentGuide.trailingAnchor].active = YES;
这工作得很好,除了在某些情况下 (1) 标准 UITableViewCell 不 使用 readableContentGuide
,所以将标准单元格与我的自定义单元格混合看起来不好,因为它们的边缘没有对齐。此处您看到 4 个自定义单元格,顶部和底部各有一个标准单元格:
(1) 它发生在这些场景中:
- 在 iPhone 有槽口的设备上,当设备横向放置时
- 在 iPad 设备上,纵向和横向均如此
我曾尝试使用 layoutMarginsGuide
而不是 readableContentGuide
,但这会导致许多约束错误(“无法同时满足约束。”在 Xcode 的调试输出中)。我也试过设置
self.tableView.cellLayoutMarginsFollowReadableWidth = YES;
在 table 视图中使用我的自定义单元格,这是有效的,因为标准单元格现在的边缘与我的自定义单元格位于同一位置。但我不喜欢这种解决方法,首先是因为这意味着我必须为每个想要使用我的自定义单元格的 table 视图进行特殊设置,其次是因为它不必要地减少了可用于数据显示的宽度.
我好像漏掉了什么。是否有一种简单、标准的方法可以如何使用布局指南来布局自定义 UITableViewCell 的内容,以便自定义单元格内容的边缘与标准单元格的边缘位于同一位置?
您应该可以使用单元格的 .contentView.layoutMarginsGuide
:
UILayoutGuide *g = self.contentView.layoutMarginsGuide;
[NSLayoutConstraint activateConstraints:@[
[stackView.topAnchor constraintEqualToAnchor:g.topAnchor],
[stackView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor],
[stackView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor],
[stackView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor],
]];
如果这给你“无法同时满足约束”的消息,但布局看起来正确——这在单元格中使用堆栈视图时很常见——你可以忽略这些消息或给予底部锚点低于要求的优先级:
UILayoutGuide *g = self.contentView.layoutMarginsGuide;
NSLayoutConstraint *c = [stackView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor];
c.priority = UILayoutPriorityDefaultHigh;
[NSLayoutConstraint activateConstraints:@[
[stackView.topAnchor constraintEqualToAnchor:g.topAnchor],
[stackView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor],
[stackView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor],
c,
]];