2

序文: これはかなり抽象的な質問です。

セルの高さに応じて異なる画像を使用するセルがいくつかありUITableViewます (50px から 1000px までの高さで 50px 単位で)。cellForRowAtIndexPathアプリが最初にロードされたときに、最初の 3 つのセル (3 つすべてが画面上にあるかどうかに関係なく) の高さが 100px であると報告され、下にスクロールして再び上に戻ると、それらの高さが元に戻るという奇妙な問題が発生しています。正しい値に。画面上の高さの変更はなく、使用される画像のみが変更さcell.frame.size.heightれ、NSLogステートメントの値が変更されます。

私は と にログインしてheightForRowAtIndexPathおりcellForRowAtIndexPath、彼らが を離れたときに高さが正しいことを確認できますheightForRowAtIndexPath。しかし、 を入力するcellForRowAtIndexPathと、最初の 3 つの高さがすべて均一に 100 に設定されます。次に、これらの 3 つのセルが画面外になるまで下にスクロールし、次に上にスクロールすると、.height値が正しい値に変更されます。

要約すると、私の質問は次のとおりです。

これらの最初のいくつかのセルの値を変更する可能性のあるコードの最後heightForRowAtIndexPathと最初の間に呼び出されるコードはありますか?cellForRowAtIndexPathcell.frame.size.height

この問題が最初の 3 つのセルでのみ発生するのはなぜですか? そして、しばらくしてリロードすると元に戻るのはなぜですか? 再利用識別子が原因である可能性があると思いましたが、最初にロードされたときにまだその識別子が割り当てられているので、それは問題ではありませんか?

編集: 100px の高さは、ストーリーボードのプロトタイプ セルの行の高さから来ていると思います。それを 101px に変更すると、最初の 3 つのセルは最初は 101px になります。

編集:画像を設定するために使用しているコードは次のとおりです。この部分は機能していますが、操作する値が間違っています:

UIImage *cappedBG;
float cellHeight = cell.contentView.frame.size.height;

if (cellHeight <= 51) {
    cappedBG = [[UIImage imageNamed: @"bg50.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else if (cellHeight <= 101) {
    cappedBG = [[UIImage imageNamed: @"bg100.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else if (cellHeight <= 151) {
    cappedBG = [[UIImage imageNamed: @"bg150.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else if (cellHeight <= 201) {
    cappedBG = [[UIImage imageNamed: @"bg200.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else {
    cappedBG = [[UIImage imageNamed: @"bg250.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} 
4

3 に答える 3

4

のセルのフレームに頼ることはできませんtableView:cellForRowAtIndexPath:。そのメソッドで構成するセルのフレームは、コードがこのメソッドから返された後に設定されます。

得られる値は、その特定の行の実際の高さではありません。キューから取り出されたばかりのセルから高さを取得します。デキューするセルがない場合は、作成されたばかりのセルの高さが使用されます。100 は、おそらくストーリーボード/ペン先のセルの高さです。
この高さは、表示されるセルの高さとは関係ありません。

tableView:heightForRowAtIndexPath:行の高さはすでに計算しているので、この値を使用します。

float cellHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];

if (cellHeight <= 51) {
    cappedBG = [[UIImage imageNamed: @"bg50.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
...
于 2013-03-20T10:32:51.687 に答える
1

現在、あなたの質問を見た後、あなたは異なるセルの高さ(スクロールされたとき)で問題を抱えていると思います。heightForRowAtIndexPathに正しい値を指定していないと思います。

以下は私が書いた簡単なコードです。このコードでは、テーブルに20行が表示され、別の行のサイズが異なります(区別するために異なる色を使用しました)

#pragma mark - TableView DataSource Methods

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.row %2 == 0) return 50;
    else return 100;
}

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *stringCellIdentifier = @"BookOutVehicleCell";

    UITableViewCell *tableViewCell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:stringCellIdentifier];

    if (tableViewCell == nil)
        tableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:stringCellIdentifier] autorelease];

    if(indexPath.row %2 == 0) tableViewCell.contentView.backgroundColor = [UIColor redColor];
    else  tableViewCell.contentView.backgroundColor = [UIColor greenColor];

       return tableViewCell;

}

#pragma mark - TableView Delegate Methods
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

}

これが出力です。

ここに画像の説明を入力してください

この場合、テーブルビューを上下にスクロールしても、行の高さは変わりません。

お役に立てれば。そして、私があなたの質問を誤解した場合は申し訳ありません。コードスニペットを提供すると便利です。それは私たちに問題についてのより良い考えを与えるでしょう。

編集: 問題の私の理解によると、各行/セルの正しい高さを取得していますが、セルの高さごとに異なる画像を表示するセル内の画像ビューを使用しています。次のことがうまくいくかどうかを確認してください。

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *stringCellIdentifier = @"BookOutVehicleCell";

        UITableViewCell *tableViewCell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:stringCellIdentifier];

        if (tableViewCell == nil)
            tableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:stringCellIdentifier] autorelease];

       //Check your height here and use appropriate image 
       if(cell.contentView.frame.size.height <100)
       {
            image = "xxx.png";
       }
       else
       if(cell.contentView.frame.size.height >=100 && cell.contentView.frame.size.height <200)
       {
           image = "yyy.png";
       }


    }

ありがとう。

于 2013-03-19T14:38:16.270 に答える
1

cellForRowAtIndexPathでセルのレイアウトを実際に行うべきではありません。

これを行う最良の方法は、必要なすべてのUI要素を含むUITableViewCellサブクラスを作成することです。

次に、サブクラスで。をオーバーライドできます- (void)layoutSubviews

このようにして、すべてをView Controllerに配置するのではなく、すべてを分離しておくことができます。

于 2013-03-19T14:09:18.510 に答える