2017-04-19 19 views
0

ラベルのテキストが変更されたときに、UITableViewCellの高さを更新することに問題があります。ラベルのテキストが変更されたときにUITableViewCellの高さを再計算

私は事を説明するのが良くないので、私はGithubにレポを作成しました。ちょうどグラブして実行することができます。セルを再利用するために、テーブルビューを上下にスクロールすると問題が表示されるはずです。私が何をしたか


た:

  • 私は自己サイズのセルとテーブルビューを作成しました。
  • 各セルは、UILabelです。
  • 私は、UILabelの内容を決定するビューモデルを持っています。
  • RxSwiftを使用して、ビューモデルの変更を登録し、それに応じてUITableのテキストを更新します。
  • 同時に、セルはデリゲート(この場合はUITableViewController)に高さの再計算を依頼します。
  • デリゲートはtableView.beginUpdatestableView.endUpdatesを呼び出してセルの高さを更新します。

結果

  • 最初のセルを再利用して、下方向にスクロールしますように、私はテーブルビューをスクロールアップする場合。最初のセルの内容は、私がを試してみました何(。第二のセルは最初のものの複製になります)

テーブルビュー間で複製されます。

  • 私はtableView.reloadData()を呼び出そうとしました。 - >無限ループ
  • 私はtableView.reloadRows()に電話しようとしました - >これは動作しますが、理由はわかりません。私が達成したい何

  • 私はRxが動作する方法を好むので、一緒のRxとMVVMを維持したいです。
  • セルのラベルテキストを変更できるようにしたい場合、セルの高さをテキストに合わせて更新することができます。

いくつかのコードスニペット:(それはレポをチェックアウトして行く方が良いいただきたいが。):のUITableViewController

セルレジスタビューモデル

override func awakeFromNib() { 
    super.awakeFromNib() 

    viewModel.title 
     .observeOn(MainScheduler.instance) 
     .subscribe(onNext: { [weak self] title in 
      guard let cell = self else { return } 

      cell.label.text = title 
      cell.delegate?.requestSizeRecalculate(cell: cell) 
     }) 
     .disposed(by: disposeBag) 
} 

デリゲートメソッド

func requestSizeRecalculate(cell: SimpleCell) { 
    print("Size recalculating....") 

    method1(cell: cell) 
    //method2(cell: cell) 
    //method3(cell: cell) 
} 

private func method1(cell: SimpleCell) { 
    // Will not cause infinite loop but will have duplicates. 
    cell.setNeedsUpdateConstraints() 
    tableView.beginUpdates() 
    tableView.endUpdates() 
} 

private func method2(cell: SimpleCell) { 
    // Will cause infinite loop 
    tableView.reloadData() 
} 

private func method3(cell: SimpleCell) { 
    // This method works pretty well. 
    if let indexPath = tableView.indexPath(for: cell) { 
     tableView.reloadRows(at: [indexPath], with: .none) 
    } 
} 

それはStackOverflowの上の質問をして私の最初の時間です。私は物事をもっと複雑にするかもしれないことを知っています。しかし、誰かがあなたの経験に基づいて提案を提供できる場合、私は非常に感謝します!

答えて

-1

あなたのコードを見ました。今度は、行の高さを計算する必要はありません。あなたがトップ、リーディング、ボトム、そしてトレーリングの制約を与えたとき。 Xcodeは、ラベルの高さを計算し、セルのサイズを増加させます。 1つのメソッドを渡す必要があります。

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
{ 

    return UITableViewAutomaticDimension 
} 

あなたはすべてのことを正しく行っています。あなたは上記のメソッドを書く必要があります。今この方法は必要ありません。

extension ViewController: SimpleCellDelegate { 
    func requestSizeRecalculate(cell: SimpleCell) { 
     print("Size recalculating....") 

私はあなたのプロジェクトをこのリンクに変更を加えてアップロードしました。自己サイジングをテストするために、配列に1つの大きなテキストを追加しました。ここで

Self Sizing Tableview

アウトのスクリーンショットです: -

私はこの答えはあなたのために有用であると思います。

enter image description here

+0

ねえ、感謝を。しかし、あなたが私のコードを見れば。私は 'viewDidLoad'メソッドで' rowHeight'を指定しました。 –

+0

私は実際にセルフサイズのセルがどのように動作するかを知っています。しかし、ここでの問題はセルの初期高さではありません。それは、基になるモデルを変更した後のセルの高さです。私の場合、ラベルのテキストを長めに変更すると、高さが再計算されるようにセルをリロードする必要があります。 –

+0

これは動作していないようです - テーブルビュー内に他のビューがある場合、その値を変更することによって、それらをスカッシュするようです。私はそれがここで間違った文脈で使われているかもしれないと思う.. –

1

あなたは行うことができます応答のための

tableView.beginUpdates() 
tableView.reloadRows(at: [indexPathOfCell], with: .none) 
tableView.endUpdates() 
関連する問題