さらに調査すると(セルのサブビュー階層を表示)、Interface Builderはセル内にサブビューを配置しますが、そのcontentView
ようには見えません。
この問題の根本的な原因は、iOS6の自動レイアウトでした。セルが編集モードになっている(そしてインデントされている)と、contentView
もインデントされます。したがって、内にあるために、内のすべてのサブビューcontentView
が移動(インデント)されるのは当然contentView
です。ただし、Interface Builderによって適用されるすべての自動レイアウト制約はUITableViewCell
、ではなく、それ自体に関連しているように見えcontentView
ます。contentView
これは、インデントがあっても、その中に含まれるサブビューはそうではないことを意味します-制約が担当します。
たとえばUILabel
、セルにaを配置すると(セルの左側から10ポイント配置すると)、IBは自動的に「水平スペース(10)」という制約を適用しました。ただし、この制約はUITableViewCell
NOTに関連していcontentView
ます。これは、セルがインデントされてcontentView
移動しても、ラベルは、の左側から10ポイントを維持するという制約に準拠しているため、配置されたままになることを意味しUITableViewCell
ます。
残念ながら(私が知る限り)、これらのIBによって作成された制約をIB自体から削除する方法はないため、ここで問題を解決しました。
UITableViewCell
セルのサブクラス内に、IBOutlet
という制約のforを作成しました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
ので、この要素の制約/配置を修正すると、他のすべてがそれに続き、正しく配置されました。ただし、より複雑なレイアウトを使用している場合は、他のサブビューに対してもこれを行う必要がある場合があります。