经过进一步调查(查看单元格的子视图层次结构),Interface Builder 确实将子视图放置在单元格的子视图中。contentView
,它只是看起来不像。
该问题的根本原因是 iOS 6 自动布局。当单元格置于编辑模式(并缩进)时contentView
也是缩进的,因此理所当然的是,contentView
将由于在范围内而移动(缩进)contentView
。然而,Interface Builder 应用的所有自动布局约束似乎都与UITableViewCell
本身,而不是contentView
。这意味着即使contentView
缩进,其中包含的子视图没有 - 约束负责。
例如,当我放置一个UILabel
进入单元格(并将其放置在距离单元格左侧 10 个点的位置) IB 自动应用约束“水平空间 (10)”。然而,这个约束是相对于UITableViewCell
不是contentView
。这意味着当单元格缩进时,contentView
移动时,标签保持原状,因为它符合距离左侧 10 点的约束UITableViewCell
.
不幸的是(据我所知)没有办法从 IB 本身内部删除这些 IB 创建的约束,所以这就是我解决问题的方法。
内UITableViewCell
细胞的子类,我创建了一个IBOutlet
对于称为的约束cellLabelHSpaceConstraint
。您还需要一个IBOutlet
对于标签本身,我称之为cellLabel
。然后我实施了-awakeFromNib
方法如下:
- (void)awakeFromNib {
// -------------------------------------------------------------------
// We need to create our own constraint which is effective against the
// contentView, so the UI elements indent when the cell is put into
// editing mode
// -------------------------------------------------------------------
// Remove the IB added horizontal constraint, as that's effective
// against the cell not the contentView
[self removeConstraint:self.cellLabelHSpaceConstraint];
// Create a dictionary to represent the view being positioned
NSDictionary *labelViewDictionary = NSDictionaryOfVariableBindings(_cellLabel);
// Create the new constraint
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[_cellLabel]" options:0 metrics:nil views:labelViewDictionary];
// Add the constraint against the contentView
[self.contentView addConstraints:constraints];
}
总之,上面的内容将删除 IB 自动添加的水平间距约束(这对于UITableViewCell
而不是contentView
)然后我们定义并添加我们自己的约束contentView
.
就我而言,其他所有UILabels
单元格中的位置是根据cellLabel
因此,当我修复此元素的约束/定位时,所有其他元素都会效仿并正确定位。但是,如果您有更复杂的布局,那么您可能也需要对其他子视图执行此操作。