UITableViewヘッダーセクションのカスタマイズ


141

UITableViewセクションごとにヘッダーをカスタマイズしたい。これまでのところ、実装しました

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

このUITabelViewDelegate方法。私がしたいことは、各セクションの現在のヘッダーを取得UILabelし、サブビューとして追加することです。

今のところ、それを達成することはできません。なぜなら、デフォルトのセクションヘッダーを取得するためのものが見つからなかったからです。最初の質問、デフォルトのセクションヘッダーを取得する方法はありますか?

それが不可能な場合は、コンテナビューを作成する必要がありますUIViewが、今回はデフォルトの背景色、影の色などを設定する必要があります。セクションのヘッダーをよく見ると、すでにカスタマイズされているためです。

各セクションヘッダーのこれらのデフォルト値を取得するにはどうすればよいですか?

皆さん、ありがとうございました。


1
使用の何が問題になっていtableView:titleForHeaderInSection:ますか?
ボルデン2013年

それはを返しますNSString、私はカスタムフォントを設定する必要があるので、使用する場合はできませんtableView:titleForHeaderInSection:
limon

または、画像を使用してデフォルトのセクションヘッダーを模倣することもできます。teehanlax.com/blog/ios-6-gui-psd-iphone-5
Desdenova

@limon:セクションヘッダーの実装方法:stackoverflow.com/a/32261262/1457385
浅いThought Thought

回答:


288

あなたはこれを試すことができます:

 -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 18)];
    /* Create custom view to display section header... */
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, tableView.frame.size.width, 18)];
    [label setFont:[UIFont boldSystemFontOfSize:12]];
     NSString *string =[list objectAtIndex:section];
    /* Section header is in 0th index... */
    [label setText:string];
    [view addSubview:label];
    [view setBackgroundColor:[UIColor colorWithRed:166/255.0 green:177/255.0 blue:186/255.0 alpha:1.0]]; //your background color...
    return view;
}

それはあなたがあなたが設定したいあなたのBGカラーWateverカラーです
Lochana Ragupathy

それが問題だ、私はあなたが書いたことをすでにやった。しかし、セクションヘッダーのデフォルトの背景色はわかりません。しかし、私はそれを正確にデフォルトのセクションヘッダーにする必要があります。
limon 2013年


UILabelのbackgroundColorも必ず設定してください。自分のバックグラウンドがはっきりしていなかったとき、私は少し混乱していました。
shulmey 2013

3
NSStringのリストとは何ですか* string = [list objectAtIndex:section]; 誰でも教えてもらえる
Nisha Gupta

45

選択した答えtableView :viewForHeaderInSection:は正しいです。

ここでヒントを共有します。

ストーリーボード/ xibを使用している場合は、別のプロトタイプセルを作成して、「セクションセル」に使用できます。ヘッダーを構成するコードは、行セルの構成方法に似ています。

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    static NSString *HeaderCellIdentifier = @"Header";

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

    // Configure the cell title etc
    [self configureHeaderCell:cell inSection:section];

    return cell;
}

14
このソリューションには多くの問題があります。まず、「tableView(tableView:UITableView、canEditRowAtIndexPath indexPath:NSIndexPath)-> Bool」を実装すると、スライドするとセクションヘッダーが行に沿って移動することがわかります。これを回避するには、代わりにcell.contentViewを返す必要があります。より大きな問題は、このソリューションでは、セクションヘッダーを長押しするとアプリがクラッシュすることです。正しい方法は、UITableViewHeaderFooterViewを拡張するnibを作成し、それをtableviewに登録して、このメソッドで返すことです。iOS8でテスト
カチ

@Kachiソリューションはあなたが述べたように使用してviewForHeaderInSectionいませんcanEditRowAtIndexPath。私はあなたが言ったクラッシュを確認したことはありませんが、長押しするとクラッシュがどのように引き起こされるかを教えてくれますか?
samwize 2015

1
つまり、このソリューションを実装し、canEditRowAtIndexPathを実装すると、cell.contentViewを返さない場合、ヘッダーも削除する一番上の行と一緒にスライドすることがわかります。このSOの記事を参照してください:stackoverflow.com/questions/26009722/... メッセージは割り当てが解除されたオブジェクトに送信されますしようとするため、長押しがクラッシュします。このSOの記事を参照してください。stackoverflow.com/questions/27622290/...
カチ

1
UITableViewCellヘッダービューとして使用しないでください。視覚的な不具合をデバッグするのは非常に難しくなります。セルがデキューされる方法が原因でヘッダーが消えることがありUITableViewCellUITableViewヘッダーに属していないことに気付くまで何時間かを探します。
raven_raven 2017

UITableViewCellヘッダーとしての使用は単に間違っています。
Alex Zavatone

31

Lochana Tejasの Swiftバージョンの回答:

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 18))
    let label = UILabel(frame: CGRectMake(10, 5, tableView.frame.size.width, 18))
    label.font = UIFont.systemFontOfSize(14)
    label.text = list.objectAtIndex(indexPath.row) as! String
    view.addSubview(label)
    view.backgroundColor = UIColor.grayColor() // Set your background color

    return view
}

1
ビュー内にあるテキストごとにラベルの高さを動的にする方法は?
Pratik Shah 2017

overrideキーワードは冗長です。さらに、ヘッダービューを再作成するのではなく、再利用することを検討してください。
Vadim Bulavin 2017

17

デフォルトのヘッダービューを使用する場合は、そのテキストのみを変更できます

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

Swiftの場合:

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

ビューをカスタマイズする場合は、自分で新しいビューを作成する必要があります。


10

UITableViewHeaderFooterViewを使用しないのはなぜですか?


-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)sectionも使用しない場合にのみ、これを使用できます。
SAHM 2013年

1
完全に有効な答え。また、UITableViewHeaderFooterViewを使用すると、セルと同じようにビューを再利用できます。
Gregzo 2014年

6
@dmarsi私はそれらが廃止されているという証拠を発見していません。
フォークス

8

headerInSectionが表示されない場合は、これを試すことができます。

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 45;
}

これは、指定されたセクションのヘッダーの高さを返します。


1
答えを詳しく説明しますか?
CinCout、2015

メソッドフックでセクションヘッダーの「高さ」を指定しない限り、ヘッダーセクションは表示されません。高さが指定されていない場合、UITableViewはデフォルトでヘッダーを表示しません。@CinCout
theprojectabot

6

lochanaとestemendozaのSwift 3バージョンの回答:

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let view = UIView(frame: CGRect(x:0, y:0, width:tableView.frame.size.width, height:18))
    let label = UILabel(frame: CGRect(x:10, y:5, width:tableView.frame.size.width, height:18))
    label.font = UIFont.systemFont(ofSize: 14)
    label.text = "This is a test";
    view.addSubview(label);
    view.backgroundColor = UIColor.gray;
    return view

}

また、実装する必要があることにも注意してください。

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 100;
}

5

これを試して......

override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) 
{
    // Background view is at index 0, content view at index 1
    if let bgView = view.subviews[0] as? UIView
    {
        // do your stuff
    }

    view.layer.borderColor = UIColor.magentaColor().CGColor
    view.layer.borderWidth = 1
}

5

他の答えはデフォルトのヘッダービューを再作成するのに適していますが、実際には主な質問には答えません:

デフォルトのセクションヘッダーを取得する方法はありますか?

方法がありtableView:willDisplayHeaderView:forSection:ます- デリゲートに実装するだけです。デフォルトのヘッダービューは2番目のパラメーターに渡され、そこからキャストしてUITableViewHeaderFooterView必要に応じてサブビューを追加/変更できます。

Obj-C

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    UITableViewHeaderFooterView *headerView = (UITableViewHeaderFooterView *)view;

    // Do whatever with the header view... e.g.
    // headerView.textLabel.textColor = [UIColor whiteColor]
}

迅速

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
{
    let headerView = view as! UITableViewHeaderFooterView

    // Do whatever with the header view... e.g.
    // headerView.textLabel?.textColor = UIColor.white
}

キャストする必要はありません。必要なものをビューに追加するだけです。実際、に割り当てない限り、新しいオブジェクトを作成しても何も起こりませんview
Alex Zavatone 2017年

@AlexZavatoneそうです、ビューを追加するだけの場合はキャストする必要はありません。テキストラベルなどのデフォルトビューの一部をカスタマイズする場合に役立ちます。
クレイグブラウン

4
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    //put your values, this is part of my code
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 30.0f)];
    [view setBackgroundColor:[UIColor redColor]];
    UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(20, 5, 150, 20)];
    [lbl setFont:[UIFont systemFontOfSize:18]];
    [lbl setTextColor:[UIColor blueColor]];
    [view addSubview:lbl];

    [lbl setText:[NSString stringWithFormat:@"Section: %ld",(long)section]];

    return view;
}

4

これが最も簡単な解決策です。次のコードは、カスタムセクションヘッダーの作成に直接使用できます。

 -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    SectionHeaderTableViewCell *headerView = [tableView dequeueReusableCellWithIdentifier:@"sectionHeader"];

    //For creating a drop menu of rows from the section
    //==THIS IS JUST AN EXAMPLE. YOU CAN REMOVE THIS IF-ELSE.==
    if (![self.sectionCollapsedArray[section] boolValue])
    {
        headerView.imageView.image = [UIImage imageNamed:@"up_icon"];
    }
    else
    {
        headerView.imageView.image = [UIImage imageNamed:@"drop_icon"];
    }

    //For button action inside the custom cell
    headerView.dropButton.tag = section;
    [headerView.dropButton addTarget:self action:@selector(sectionTapped:) forControlEvents:UIControlEventTouchUpInside];

    //For removing long touch gestures.
    for (UIGestureRecognizer *recognizer in headerView.contentView.gestureRecognizers)
    {
        [headerView.contentView removeGestureRecognizer:recognizer];
        [headerView removeGestureRecognizer:recognizer];
    }

    return headerView.contentView;
}

注:SectionHeaderTableViewCellは、ストーリーボードで作成されたカスタムUITableViewCellです。


SectionHeaderTableViewCell-宣言されていない識別子の使用
Boris Gafurov

@BorisGafurov SectionHeaderTableViewCellは、ストーリーボードで作成したUITableViewCellに付けた名前の例です。
アニッシュクマー2017年

2

私があなただったら、NSStringを指定してUIViewを返すメソッドを作成します。例えば

+ (UIView *) sectionViewWithTitle:(NSString *)title;

このメソッドの実装では、UIViewを作成し、設定するプロパティを含むUILabelをUILabelに追加します。もちろん、タイトルを指定されたものに設定します。


はい、できますが、私の質問は、デフォルトのセクションヘッダーの背景、シャドウ値を取得する方法です。残りは簡単に実装できます。
リモン2013年

デフォルトのセクションヘッダーの背景の意味
Lochana Ragupathy 2013年

1
まあ、最も簡単な方法は、デジタルカラーメーターアプリケーションを使用して必要な色を取得することです。私が知る限り、コードでそれらを取得するのは
困難

2

Swiftでの@samwizeのソリューション(彼に賛成投票してください!)。ヘッダー/フッターセクションにも同じリサイクルメカニズムを使用して素晴らしい:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let settingsHeaderSectionCell:SettingsHeaderSectionCell = self.dequeueReusableCell(withIdentifier: "SettingsHeaderSectionCell") as! SettingsHeaderSectionCell

    return settingsHeaderSectionCell
}

2
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    if([view isKindOfClass:[UITableViewHeaderFooterView class]]){

        UITableViewHeaderFooterView *headerView = view;

        [[headerView textLabel] setTextColor:[UIColor colorWithHexString:@"666666"]];
        [[headerView textLabel] setFont:[UIFont fontWithName:@"fontname" size:10]];
    }
}

セクションヘッダーのtextLabelのフォントを変更する場合は、willDisplayHeaderViewで変更します。テキストを設定するには、viewForHeaderInSectionまたはtitleForHeaderInSectionで設定できます。幸運を!


2

コピーして貼り付ける2019年の完全な例

最初にストーリーボードで「グループ化」を設定します。初期化時に行う必要があります。後で実際に設定することはできないため、ストーリーボードで覚えておくと簡単です。

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

次、

Appleのバグのため、heightForHeaderInSectionを実装する必要があります。

func tableView(_ tableView: UITableView,
                   heightForHeaderInSection section: Int) -> CGFloat {
    return CGFloat(70.0)
}

まだAppleのバグがあります-今から10年間-ない場合、最初のヘッダー(つまり、インデックス0)が表示されません。 heightForHeaderInSection呼び出し。

だから、tableView.sectionHeaderHeight = 70単に機能しない、それは壊れている。ます。

フレームを設定しても何も起こりません:

viewForHeaderInSection、単にのUIViewを作成します()。

それは無意味です/ あなたがUIView(frame ...)なら何も達成しませんiOSがテーブルによって決定されるようにビューのサイズを設定するだけなので、。

したがって、の最初の行はviewForHeaderInSection単純にlet view = UIView()なり、それがあなたが返すビューです。

func tableView(_ tableView: UITableView,
                       viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView()
    
    let l = UILabel()
    view.addSubview(l)
    l.bindEdgesToSuperview()
    l.backgroundColor = .systemOrange
    l.font = UIFont.systemFont(ofSize: 15)
    l.textColor = .yourClientsFavoriteColor
    
    switch section {
    case 0:
        l.text =  "First section on screen"
    case 1:
        l.text =  "Here's the second section"
    default:
        l.text =  ""
    }
    
    return view
}

それだけです-それ以外のものは時間の無駄です。

別の「うるさい」アップルの問題。


上記で使用した便利な拡張機能は次のとおりです。

extension UIView {
    
    // incredibly useful:
    
    func bindEdgesToSuperview() {
        
        guard let s = superview else {
            preconditionFailure("`superview` nil in bindEdgesToSuperview")
        }
        
        translatesAutoresizingMaskIntoConstraints = false
        leadingAnchor.constraint(equalTo: s.leadingAnchor).isActive = true
        trailingAnchor.constraint(equalTo: s.trailingAnchor).isActive = true
        topAnchor.constraint(equalTo: s.topAnchor).isActive = true
        bottomAnchor.constraint(equalTo: s.bottomAnchor).isActive = true
    }
}

1

魔法のようにすばやくテーブルビューヘッダーを追加する

最近これを試しました。

UITableView全体でヘッダーが1つだけ必要でした。

TableViewの上にUIImageViewが欲しかったように。したがって、UITableViewCellの上にUIImageViewを追加し、自動的にtableViewHeaderとして追加されました。次に、ImageViewをViewControllerに接続し、画像を追加します。

初めてこういうことをしたので戸惑いました。したがって、私の混乱を解消するために、MainStoryBoardのxml形式を開いて、イメージビューがヘッダーとして追加されていることを確認します。

それは私のために働いた。xCodeと迅速に感謝します。


1

このデリゲートメソッドを呼び出す

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

return @"Some Title";
}

これにより、動的なタイトルを持つデフォルトのヘッダーを自動的に追加する機会が与えられます。

再利用可能でカスタマイズ可能なヘッダー/フッターを使用できます。

https://github.com/sourov2008/UITableViewCustomHeaderFooterSection


1

swif 4.2

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let header = view as? UITableViewHeaderFooterView else { return }

    header.textLabel?.textAlignment = .center // for all sections

    switch section {
    case 1:  //only section No.1
        header.textLabel?.textColor = .black
    case 3:  //only section No.3
        header.textLabel?.textColor = .red
    default: //
        header.textLabel?.textColor = .yellow
    }
}


0

タイトルをtableViewヘッダーに追加するだけの場合は、ビューを追加しないでください。Swift 3.xでは、コードは次のようになります。

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    var lblStr = ""
    if section == 0 {
        lblStr = "Some String 1"
    }
    else if section == 1{
        lblStr = "Some String 2"
    }
    else{
        lblStr = "Some String 3"
    }
    return lblStr
}

ヘッダーのタイトルを取得する配列を実装できます。


0

独自のセクションヘッダーを再構築するのではなく、元の質問(4年後)に戻ると、iOSは、デフォルトのヘッダーが構築された直後に(willDisplayHeaderView:forSection:を使用して)単に呼び出すことができます。たとえば、セクションヘッダーの右端にグラフボタンを追加したいと思います。

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    UITableViewHeaderFooterView * header = (UITableViewHeaderFooterView *) view;
    if (header.contentView.subviews.count >  0) return; //in case of reuse
    CGFloat rightEdge = CGRectGetMaxX(header.contentView.bounds);
    UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(rightEdge - 44, 0, 44, CGRectGetMaxY(header.contentView.bounds))];
    [button setBackgroundImage:[UIImage imageNamed:@"graphIcon"] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(graphButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [view addSubview:button];
}

0

使用する tableView: willDisplayHeaderView:表示されようとしているときにビューをカスタマイズためにします。

これにより、ヘッダービュー全体を自分で再作成する代わりに、ヘッダービュー用に既に作成されているビューを取得して拡張できるという利点があります。

以下は、BOOLに基づいてヘッダーセクションに色を付け、詳細テキスト要素をヘッダーに追加する例です。

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
//    view.tintColor = [UIColor colorWithWhite:0.825 alpha:1.0]; // gray
//    view.tintColor = [UIColor colorWithRed:0.825 green:0.725 blue:0.725 alpha:1.0]; // reddish
//    view.tintColor = [UIColor colorWithRed:0.925 green:0.725 blue:0.725 alpha:1.0]; // pink

    // Conditionally tint the header view
    BOOL isMyThingOnOrOff = [self isMyThingOnOrOff];

    if (isMyThingOnOrOff) {
        view.tintColor = [UIColor colorWithRed:0.725 green:0.925 blue:0.725 alpha:1.0];
    } else {
        view.tintColor = [UIColor colorWithRed:0.925 green:0.725 blue:0.725 alpha:1.0];
    }

    /* Add a detail text label (which has its own view to the section header… */
    CGFloat xOrigin = 100; // arbitrary
    CGFloat hInset = 20;
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(xOrigin + hInset, 5, tableView.frame.size.width - xOrigin - (hInset * 2), 22)];

    label.textAlignment = NSTextAlignmentRight;

    [label setFont:[UIFont fontWithName:@"Helvetica-Bold" size:14.0]
    label.text = @"Hi.  I'm the detail text";

    [view addSubview:label];
}

0

Swift 4.2

Swift 4.2では、テーブルの名前が少し変更されています。

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 18))
        let label = UILabel(frame: CGRect(x: 10, y: 5, width: tableView.frame.size.width, height: 18))
        label.font = UIFont.systemFont(ofSize: 14)
        label.text = list.objectAtIndex(section) as! String
        view.addSubview(label)
        view.backgroundColor = UIColor.gray // Set your background color

        return view
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.