1

プログラムでテーブルビューセルの右上にラベルを追加しようとしています。

[label addConstraint:[NSLayoutConstraint
    constraintWithItem:label
    attribute:NSLayoutAttributeRight
    relatedBy:NSLayoutRelationEqual
    toItem:cell
    attribute:NSLayoutAttributeRight
    multiplier:1.0
    constant:0]];

これは、私が推測しているビューのサブツリーの外側にある何かを参照したというエラーを出しますが、それはセル自体ですか?上と右に2つの別々の制約が必要ですか?

制約を使用して正しく実行したいのですが、セル幅を手動で取得してラベルの位置を変更することも試みました。ユーザーがデバイスを回転させた場合に備えて、方向変更メソッドにコードの複製を追加する必要があります。制約を使用できない場合は、この方法を使用できますが、セルの正しい幅を取得できません。これを試しました。

[label setFrame:CGRectMake(cell.frame.size.width-318, 10, 308, 30)];

cell.frame.size.widthセルの正しい幅が取得されていないようです。

編集:セルの幅はその中のコンテンツに相対的であることがわかったので、上記の行を変更tableView.frame.size.widthして、ジョブを実行するtableView全体のwithを取得しました。それが可能かどうかを確認するために、制約に関するフィードバックを引き続き受け取りたいと思います。

編集:これは私がセルとラベルを設定する方法です...

NSString *cellId = @"cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if(cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
}

UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(10, 10, 308, 30)];
label.text = @"Whatever text";

// Contraint added here

[cell.contentView addSubview: label];

編集: `@frozendevilに感謝します

正しい制約を適用した後、ラベルの幅を設定するために使用した最終的なコードを表示するためだけに...

[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:200]];
4

2 に答える 2

3

一般にUITableViewCell、セル自体に対してビューを制限するのではなく、セルのビューを制限する必要があります-contentView。一般的なテーブルビューのベストプラクティスに従っていると仮定すると、ラベル-superviewはセルのものである必要があります。ラベル-contentViewからセルに直接制約を追加すると、レイヤーがスキップされます。


編集:この問題を数分間いじくり回すと、単一の制約スタイルコードを正しく動作させることができませんでした(編集2:再実行すると、両方のフレーバーが機能しているように見えます)が、ビジュアル形式を使用すると機能しました私のため:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        UILabel *label = [[UILabel alloc] init];
        label.text = @"Hallo!";
        label.backgroundColor = [UIColor redColor];
        [label sizeToFit];
        label.translatesAutoresizingMaskIntoConstraints = NO;

        [cell.contentView addSubview:label];

        NSDictionary *viewDict = @{@"label" : label};
        [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[label]|" options:0 metrics:0 views:viewDict]];
        [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]" options:0 metrics:0 views:viewDict]];

        /* Or this!
        [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:label
                                                                     attribute:NSLayoutAttributeRight
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:cell.contentView
                                                                     attribute:NSLayoutAttributeRight
                                                                    multiplier:1.0
                                                                      constant:0]];
        */
    }

    return cell;
}

より複雑なものが必要な場合は、内部にレイアウトするカスタムUIViewサブクラスを作成し、それをセルに追加するのが最も簡単な方法です-contentView


補遺:

ここでラベルの幅を処理する方法はいくつかあります。

1つは、属性を呼び出しconstraintWithItem:...て使用し、サイズを固定することです。NSLayoutAttributeWidthもう1つは、ビジュアルフォーマットスタイルを使用して基本的に同じことを行うことです。ラベルの圧縮抵抗を(を使用して-[UIView setContentCompressionResistancePriority:forAxis:])非常に高く設定して、値を変更せずに内容に自動的に調整されるようにするのが最善です。

自動レイアウトのビジュアルフォーマット言語に慣れていない場合は、関連するWWDCビデオを視聴し、それに慣れるためにダミーコードを作成することを強くお勧めします。自動レイアウトを使用する最も生産的な方法であることがわかりました。

于 2013-03-22T03:03:28.043 に答える
0

さて、これはすでに答えられていると思いますか?ただし、UITableViewCellのカスタムサブクラスがある場合は、次をオーバーライドすることでラベルを適切に配置するのが簡単-layoutSubviewsです。

@implementation MyCell : UITableViewCell

-(void)layoutSubviews
{
    [ super layoutSubviews ] ;

    CGRect bounds = self.contentView.bounds ;
    [ self.label sizeToFit ] ;
    self.label.anchorPoint = (CGPoint){ 1.0f, 0.0f } ;
    self.label.position = (CGPoint){ CGRectGetMaxX( bounds ), CGRectGetMinY( bounds } ;
}

@end
于 2013-03-22T05:35:08.767 に答える