web-dev-qa-db-ja.com

iOS 8:UITableViewCellの詳細テキストが正しく更新されない

tl; dr:値の変更時にiOSの自動レイアウトシステムによってdetailTextLabelのサイズを更新させることはできますか?

IOS 8以降、UITableViewCell内のdetailTextラベルに問題があった人はいますか?

テキストと詳細文字列の両方を含むテーブルがあります。最初の詳細テキストは空の文字列(@ "")です。編集画面でストーリーボードセグエを実行した後、詳細テキストの新しい値を返し、更新します。前のビューに戻った直後に値が表示されるように、viewWillAppearでテーブルをリロードしようとしました。

テーブルビューが再び表示されると、テーブルセルはテキストフィールドを上に移動して詳細テキスト用のスペースを確保しますが、詳細テキストは表示されません。編集画面に戻ってもう一度戻るまで、テキストは表示されません。

トラブルシューティングのために行ったこと:詳細テキストラベルの自動レイアウトが思ったとおりに正しく更新されていないようです。 detailTextLabelのフレームのサイズと構成をログに記録すると、これが確認されます。

ViewDidAppear内で[tablereloadData]を実行することでテキストを強制的に更新できますが、それでは気に入らないちらつき効果が残り、プロフェッショナルではないように見えます。

編集:私が行った追加のこと:[cell.detailTextLabelsizeToFit]を使用してdetailTextLabel自体のサイズを変更するように強制しました。これにより表示されますが、セル内で奇妙な方法でオフセットされます。再度編集ページに移動した後、detailTextLabelはその位置を修正します。

私が扱っているものを正確に示すために、githubリポジトリとして簡単なプロジェクトを作成しました。

https://github.com/acidaris/ios8_table_issue

私が使用しているViewControllerのメインコードも以下のとおりです。

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.table reloadData]; 
}


- (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section {
    return 1; 
}

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

    cell.textLabel.text = @"This is a test";
    cell.detailTextLabel.text = self.value;

    CGRect frame = cell.detailTextLabel.frame;
    NSLog(@"detailTextLabel x=%f y=%f width=%f height=%f",
        frame.Origin.x,frame.Origin.y,frame.size.width,frame.size.height);
    return cell; 
}

セルはStoryBoard内でプロトタイプ化されるため、dequeueReusableCellWithIdentifier:によって選択されたセルは常に定義されます。さらに、ストーリーボード内のセルタイプは字幕に設定されており、初期値が定義されている場合は表示されます。

誰かが私がこれを理解するのを手伝ってくれるなら、私は信じられないほど感謝するでしょう。

部分的な解決策

UITableViewCellをサブクラス化する場合は、レイアウトが完了したときにdetailTextLabelのフレームを変更できます。これは私がやったことであり、うまくいったようです、 しかし、6 plusでは、textLabelとdetailTextLabelの間に奇妙な境界線が表示されます。 編集:(私はこれを調整しました。)私はこの解決策が好きではありませんが、これまでのところ、これは私が出会った中で最高です。ビューを表示した後は更新されず、比較的単純です。上で述べたように、私はより良い解決策を探し続けます。

- (void)layoutSubviews {
  [super layoutSubviews]; 
  CGRect textFrame = self.textLabel.frame;
  [self.detailTextLabel sizeToFit];

  CGFloat x = textFrame.Origin.x;
  CGFloat y = textFrame.Origin.y + textFrame.size.height;

  CGSize detailSize = self.detailTextLabel.frame.size;
  CGRect newFrame = CGRectMake(x, y, detailSize.width, detailSize.height);

  self.detailTextLabel.frame = newFrame;
}

また、現在のソリューションを反映するようにGithubプロジェクトを更新しました。 Edit3:これは、真の自動レイアウトフレームの値が間違っているため、完全には機能しませんが、今のところ私の使用には機能します。

編集4:layoutSubviews関数をよりスマートになるように更新しました。ラベル内のコンテンツを固定するサイズになり、テキストラベルに対してx/y座標内にラベルを適切に配置します。

18
acidaris

同じ問題を抱えています。私の解決策は、[cell layoutSubviews]の最後にセルを返す前に-tableView:cellFForRowAtIndexPathを呼び出すことでした。これは私にとってはうまくいき、セルサブクラスのlayoutSubviewsをオーバーライドする必要はありませんでした。

19
pixbug

ストーリーボードでセグエを使用すると、セルが正しく更新されないという同じ問題があります。試した

[setNeedsLayout] and [layoutIfNeeded]

ビューとテーブルビューで動作していません。

[self.tableView reloadData] is in viewDidAppear, as it should.

それから私はpixbugからのアドバイスを試しました、そしてそれはうまくいきました。ただし、[layoutSubviews]を直接使用しないでください。そこで、tableViewやビューではなく、セル上のドキュメントでアドバイスされているものを試しました。

試した

[cell setNeedsLayout] 

しかし、これは機能しませんでした。

試した

[cell layoutIfNeeded] 

これは私のために働いた。

セルを返す前にこれを置きました。

8
Odd-Arne

IOS 8ストーリーボード(自動レイアウトが有効になっていない)でも同じ問題が発生しました。

下部に静的なテーブルビューセルがあるテーブルビューがありました。 IBでは、そのテーブルセルのコンテンツ領域にいくつかのスペースを追加しました(スタイル:「右の詳細」)。次に、コード(ViewDidLoad)で、そのセルのコンテンツを次のように更新しました...

self.copyrightsCell.detailTextLabel.text = @"<a string>";

IBスペースがないと、セルはポートレートモードでは見えませんでした。

ただし、最初のスペースを使用すると、セルのコンテンツは後で正しく表示されます。

これが誰かを助けることを願っています。

2
Paul Brady

同じ問題があります。データが利用可能であり、cell.detailTextLabel.textに割り当てられていることを確信しています。値が割り当てられると、tableViewに戻ったときに値が変更されてもちらつきがないことに気付きました。したがって、detailTextLabelへの値の最初の割り当てにのみ問題があるように見えます。

1
iCyberPaul

静的UITableViewでも同様の問題が発生しました。ラベルのテキストを変更しましたが、セルをクリックするか、ビューを強制的に更新するために何かを行わない限り、画面上で更新されません。私の回避策は、テキストを更新した後に呼び出すことでした:

tableView.reloadData()

P.Sこれは意味がありません。これは静的なテーブルビューであり、なぜ機能したのかわかりませんが、機能しました。

1
Essam Ewaisha

それで、私はこのトレッドと他の多くを追いました。これは私を正解と思われるものに導きます。 iOS 7/8が何らかの変更を加えて以来、これが私を夢中にさせたので、これが他の人に役立つことを願っています。

私の答えは、通常の処理コードをviewWillAppearに配置し、[self.tableViewリロードデータ]の代わりにこの[self.tableviewlayoutSubviews]を追加することでした。これはApple iOS 7/8で物事をより制御しやすくすることと関係があると思います。セルがどのように機能しているかに関する情報を確認したときに、その考えに思いつきました。

繰り返しますが、これが他の人がこの厄介な問題を解決するのに役立つことを願っています。

1
user1936561

Xcode 6.3.2(6D2105)OS X Yosemite 10.10.3を使用して問題を確認する正しい値が割り当てられていることを確認しましたが、1回目は表示されず、2回目は表示されます。 cell.layoutSubviews()は、ビューに更新がないように見え、layoutSubviews()を追加することでうまくいったので、私には論理的に見えました。

0

リロードデータが必要な場合、それはテーブルデータが作成されたときにロードされないことを意味すると思います。

テーブルビューがあるviewdidload(またはテーブルビューがデータを取得する前の別の場所)にデータをロードし、それに応じてセルを作成する必要があります。

通常、私は使用しているオブジェクトの配列を使用してから、おそらくご存知の[array objectAtIndex:indexpath.row]を使用します。

また、最後の段落には、重要に見える未完成の文があります。

0
Gil Sand