IB でカスタム セルを設計し、サブクラス化して、アウトレットをカスタム クラスに接続しました。セル コンテンツには、UIView (cdView) と 2 つのラベル (titleLabel と emailLabel) の 3 つのサブビューがあります。各行で使用可能なデータに応じて、セルに UIView と 2 つのラベルを表示する場合もあれば、2 つのラベルのみを表示する場合もあります。私がやろうとしているのは、UIView プロパティを非表示に設定するか、スーパービューから削除すると、2 つのラベルが左に移動する制約を設定することです。スーパービュー (セル コンテンツ) に 10 ピクセルの UIView 先行制約を設定し、次のビュー (UIView) に 10 ピクセルの UILabels 先行制約を設定しようとしました。コードの後半で、
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(IndexPath *)indexPath {
// ...
Record *record = [self.records objectAtIndex:indexPath.row];
if ([record.imageURL is equalToString:@""]) {
cell.cdView.hidden = YES;
}
}
cell.cdView を非表示にしており、ラベルを左に移動したいのですが、セル内の同じ位置に留まっています。スーパービューから cell.cdView を削除しようとしましたが、うまくいきませんでした。何をしようとしているのかを明確にするために画像を添付しました。
これをプログラムで実行する方法を知っているので、その解決策を探しているわけではありません。私が望んでいるのは、IB で制約を設定することであり、他のビューが削除または非表示になった場合にサブビューが動的に移動することを期待しています。自動レイアウトを使用して IB でこれを行うことは可能ですか?
.....
ベストアンサー1
可能ですが、少し余分な作業が必要になります。まず、概念的な事柄をいくつか理解しておく必要があります。
- 非表示のビューは描画されませんが、自動レイアウトに参加し、通常はフレームを保持し、他の関連ビューをその場所に残します。
- ビューをそのスーパービューから削除すると、関連するすべての制約もそのビュー階層から削除されます。
あなたの場合、これはおそらく次のことを意味します:
- 左側のビューを非表示に設定した場合、左側のビューは依然としてスペースを占有しているため (表示されていない場合でも)、ラベルはそのまま残ります。
- 左ビューを削除すると、ラベルの左端に対する制約がなくなるため、ラベルは曖昧な制約のままになる可能性があります。
必要なのは、ラベルを慎重に過剰に制約することです。既存の制約 (他のビューとの 10 ポイントのスペース) はそのままにして、別の制約を追加します。つまり、ラベルの左端をスーパービューの左端から 10 ポイント離し、必須ではない優先度を設定します (デフォルトの高優先度でおそらくうまく機能します)。
次に、ラベルを左に移動したい場合は、左のビューを完全に削除します。左のビューに対する必須の 10 ポイント制約は、関連するビューとともに消え、ラベルがスーパービューから 10 ポイント離れているという高優先度制約だけが残ります。次のレイアウト パスでは、ラベルが左に拡張され、端の周りの間隔を除いてスーパービューの幅がいっぱいになります。
重要な注意点が 1 つあります。左側のビューを再び表示したい場合は、ビュー階層に追加し直すだけでなく、同時にすべての制約を再設定する必要があります。つまり、そのビューが再び表示されるたびに、ビューとラベル間の 10 ポイントの間隔制約を再び設定する方法が必要になります。