web-dev-qa-db-ja.com

uitableView:titleForHeaderInSectionを使用せずにUITableViewセクションヘッダーを変更する

UITableViewのセクションのセルが選択されているときに、そのセクションのヘッダータイトルを変更しようとしています。 tableView:titleForHeaderInSectionはアプリケーションによってトリガーされるため、役に立ちません。 reloadDataを呼び出すことはできますが、アプリが表示されているすべてのセルをリロードする必要があるため、パフォーマンスが低下します。また、カスタムヘッダーを使用しようとしましたが、パフォーマンスの問題も発生します。

デフォルトのヘッダービューが使用するUILabelへのハンドルを取得し、そのテキストを手動で変更する方法はありますか?

17
mathew

システムが提供するセクションヘッダービューにアクセスするための標準APIはないようです。よりターゲットを絞った reloadSections:withRowAnimation UIKitに新しいヘッダーテキストを表示させるには?

カスタムセクションヘッダービューでどのようなパフォーマンスの問題が発生しましたか?標準のものが単なるUILabel以上のものであるとは思えません。

14
Sixten Otto

呼び出し [tableView endUpdates] パフォーマンスにあまり影響を与えることなく、望ましい結果が得られる場合があります。

[self.tableView beginUpdates];
[self.tableView endUpdates];

// forces the tableView to ask its delegate/datasource the following:
//   numberOfSectionsInTableView:
//   tableView:titleForHeaderInSection:
//   tableView:titleForFooterInSection:
//   tableView:viewForHeaderInSection:
//   tableView:viewForFooterInSection:
//   tableView:heightForHeaderInSection:
//   tableView:heightForFooterInSection:
//   tableView:numberOfRowsInSection:
24
Scott McCammon

と:

[self.tableView headerViewForSection:i]

セクションiのビューを取得して、手動で「更新」することができます

これは、ビューが自動生成されたラベルだけの場合でも機能しますが、自分でサイズを変更する必要があります。だからあなたがしようとすると:

[self.tableView headerViewForSection:i].textLabel.text = [self tableView:self.tableView titleForHeaderInSection:i];

テキストを設定しますが、ラベルサイズは設定しません。 NSStringから必要なサイズを取得して、自分で設定できます。

[label.text sizeWithFont:label.font];
16
Dr. Azrael Tod

セクションヘッダーラベルのタイトルを直接設定できます。たとえば、セクションのタイトルをゼロに設定するには、次のようにします。

UITableViewHeaderFooterView *sectionZeroHeader = [self.tableView headerViewForSection:0];
NSString *sectionZeroLabel = @"Section Zero";
[sectionZeroHeader.textLabel setText:[sectionZeroLabel uppercaseString]];
[sectionZeroHeader setNeedsLayout];

必ずセクションヘッダービューにレイアウトが必要であることを伝えてください。そうしないと、新しいテキストが切り捨てられる可能性があります。また、セクションラベルは通常すべて大文字です。

4
Ken Ryall

UITableViewは、再利用のためにセクションヘッダービューをエンキューおよびデキューしないため、すべてのセクションヘッダービューをメモリに格納することが可能かどうかを確認することもできます。これを行うには、背景などを使用して独自のセクションヘッダービューを作成する必要があることに注意してください。ただし、これにより、柔軟性と機能が少し向上します。

セクションヘッダービューにタグを付けて(独自のセクションヘッダービューを作成する必要もあります)、必要に応じてテーブルビューからそれらを取得することもできます。

1
David Liu

これはWAGであり、機能しない理由はたくさん考えられますが、サブビューを繰り返し処理して、探しているものを見つけることができませんでしたか?例えば。

for (UIView *v in self.tableView.subviews) {
    // ... is this the one?
}
0
Clay Bridges

解決策の1つは、ラベル参照を含む複数のセクションヘッダーの外部配列を管理し、それらを外部で更新することです。

0
mangesh

完全を期すために、私たち全員が探している方法は、まさにあなたが期待する名前のこのプライベートAPIです。

-(void)_reloadSectionHeaderFooters:withRowAnimation:

例えば:

[tableView _reloadSectionHeaderFooters:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic]

ただし、これを使用することはお勧めしません。

0
zeroimpl

1つのセクションのみを更新する場合は、tableView.headerViewが最適です。ヘッダーが表示されていない場合はnilを返すため、余分なヘッダーは読み込まれません。

if let header = tableView.headerView(forSection: i) {
    header.textLabel!.text = "new title"
    header.setNeedLayout()
}

表示されているすべてのセクションヘッダーを更新する場合は、ビューが表示される前にヘッダータグをセクションとして設定し、必要に応じてサブビューを列挙することをお勧めします。

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    view.tag = section
    // additional customization
}

func udpateVisibleSectionHeaders() {
    for subview in tableView.subviews {
        if let header = subview as? UITableViewHeaderFooterView {
            let section = header.tag
            header.textLabel!.text = "new title"
            header.setNeedsLayout()
        }
    }
}

setNeedsLayoutを呼び出すことを忘れないでください。そうしないと、ラベルが切り捨てられる可能性があります。

0