Налаштувати розділ заголовка UITableView


141

Я хочу налаштувати UITableViewзаголовки для кожного розділу. Поки що я реалізував

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

цей UITabelViewDelegateметод. Що я хочу зробити, це отримати поточний заголовок для кожного розділу та просто додати UILabelяк підперегляд.

Поки що я не в змозі цього досягти. Тому що я не зміг знайти нічого, щоб отримати заголовок розділу за замовчуванням. Перше питання, чи є спосіб отримати заголовок розділу за замовчуванням ?

Якщо це неможливо, мені потрібно створити перегляд контейнера, який є, UIViewале цього разу мені потрібно встановити колір тла за замовчуванням, колір тіні тощо. Тому що, якщо уважно заглянути в заголовок розділу, він вже налаштований.

Як я можу отримати ці значення за замовчуванням для кожного заголовка розділу?

Дякую вам всім.


1
Що не так з використанням tableView:titleForHeaderInSection:?
borrrden

Він повертає a NSString, мені потрібно встановити спеціальний шрифт так, я не можу, якщо використовуюtableView:titleForHeaderInSection:
limon

Або ви можете використовувати зображення, щоб імітувати заголовки розділів за замовчуванням. teehanlax.com/blog/ios-6-gui-psd-iphone-5
Дезденова

@limon: Як реалізувати заголовок розділу: stackoverflow.com/a/32261262/1457385
shallowThought

Відповіді:


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;
}

ось ваш кольоровий уайтвер, який ви хочете встановити, ви можете
Лочана Рагупатія,

Це питання, я вже зробив те, що ви написали. Але я не знаю колір тла заголовка розділу за замовчуванням, який є сірим. Але мені потрібно, щоб це був саме заголовок розділу за замовчуванням.
limon


переконайтесь, що також встановіть фон UILabel colorColor. Я знаю, що я трохи розгубився, коли мій фон не став для мене чітким.
shulmey

3
що список у рядку NSString * string = [список об’єктаAtIndex: 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, зареєструвати її без перегляду таблиці і повернути її в цьому методі. Тестовано на iOS8
Качі

@Kachi Рішення використовується viewForHeaderInSectionне так, canEditRowAtIndexPathяк ви згадали. Я ніколи не підтверджую, про що ви сказали, але ви могли б прояснити, як довге натискання спричинить збій?
samwize

1
Що я мав на увазі, що якщо ви реалізуєте це рішення І реалізуєте canEditRowAtIndexPath, ви побачите, що заголовок також буде ковзати разом із самим верхнім рядком, який ви видаляєте, якщо ви не повернете cell.contentView. Дивіться цю публікацію ТА : stackoverflow.com/questions/26009722/… Тривале натискання викликає збій, оскільки повідомлення намагається надіслати відправлене об'єкт, що розміщений. Дивіться цю публікацію ТА
Качі

1
Будь ласка, ніколи не використовуйте UITableViewCellяк перегляд заголовка. Вам буде дуже важко налагоджувати візуальні глюки - заголовок іноді зникає через те, як скасовуються комірки, і ви будете шукати годинами, чому це, поки ви UITableViewCellне зрозумієте, що не належить до UITableViewзаголовка.
raven_raven

Використовувати UITableViewCellзаголовок просто неправильно.
Алекс Заватоне

31

Швидка версія Lochana Tejas відповідає:

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
як зробити висоту мітки динамічною відповідно до тексту, який знаходиться всередині зображення?
Пратік Шах

overrideКлючове слово є зайвим. Більше того, спробуйте скористатись переглядами заголовків, а не створювати їх знову.
Вадим Булавін

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) розділ.
SAHM

1
Ідеально правильна відповідь. Крім того, використання UITableViewHeaderFooterView виграє від переробки перегляду так само, як і комірок.
Грегцо

6
@dmarsi Я не знайшов жодних доказів того, що вони застаріли.
Фокс

8

Якщо заголовокInSection не відображається, спробуйте це.

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

Це повертає висоту для заголовка певного розділу.


1
Ви хочете розробити свою відповідь?
CinCout

Розділ заголовка не показуватиме, якщо ви не вкажете методом гака «висоту» заголовка розділу. За замовчуванням UITableView не відображається заголовків, якщо не вказана висота. @CinCout
theprojectabot

6

Swift 3 версія lochana та estemendoza відповідає:

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:у своєму делегаті. Перегляд заголовка за замовчуванням буде передано у другий параметр, а звідти ви можете передати його на a, 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.
Олексій Заватоне

@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, створений на Storyboard.


SectionHeaderTableViewCell - використання незадекларованого ідентифікатора
Борис Гафуров

@BorisGafurov SectionHeaderTableViewCell - це лише приклад імені, яке я дав своєму UITableViewCell, який я створив у дошці розповідей.
Аніш Кумар

2

Якби я був ти, я би створив метод, який повертає UIView з урахуванням NSString. Наприклад

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

При реалізації цього методу створіть UIView, додайте до нього UILabel із властивостями, які ви хочете встановити, і, звичайно, встановіть його заголовок для заданого.


Так, я можу це зробити, але моє питання полягає в тому, як я можу отримати фон заголовка розділу за замовчуванням, значення тіні, інше легко реалізувати.
limon

що ти маєш на увазі під заголовком розділу за замовчуванням
Lochana Ragupathy

1
Ну, найпростіше було б скористатися програмою Digital Color Meter, щоб отримати потрібні кольори. Наскільки я можу сказати,
прийняти

2

@ рішення samwize в Swift (так що його підтримайте!). Блискуче використовуючи той самий механізм переробки також для заголовків / колонтитулів:

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. Щоб встановити текст, ви можете зробити це у поданніForHeaderInSection або titleForHeaderInSection. Удачі!


2

Повний приклад 2019 року для копіювання та вставки

Перший набір "Згрупований" на раскадровці: це повинно статися в найкоротший час, ви не можете його встановити пізніше, тому простіше запам’ятати це зробити на раскадровці:

введіть тут опис зображення

Далі,

Потрібно реалізувати висотуForHeaderInSection через помилку Apple.

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

Ще є помилка Apple - уже десять років - де вона просто не відображатиме перший заголовок (тобто індекс 0), якщо у вас немає heightForHeaderInSectionдзвінка.

Отже, tableView.sectionHeaderHeight = 70просто не працює, він зламаний .

Встановлення кадру нічого не дає:

У viewForHeaderInSectionпросто створіть UIView ().

Безглуздо / нічого не досягає, якщо ви UIView (кадр ...), оскільки 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
}

Ось і все - все інше - витрата часу.

Ще одна «метушлива» проблема Apple.


Зручне розширення, яке використовується вище:

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.

Наче я хотів UIImageView у верхній частині TableView. Тому я додав UIImageView поверх UITableViewCell і автоматично він додався як tableViewHeader. Тепер я підключаю ImageView до ViewController і додаю зображення.

Я розгубився, бо вчинив щось подібне вперше. Отже, щоб очистити мою плутанину, відкрийте формат XML MainStoryBoard і знайшов Перегляд зображень, доданий як заголовок.

Це працювало для мене. Дякую xCode і швидко.


1

викликати цей метод делегата

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

return @"Some Title";
}

це дасть можливість автоматично додати заголовок за замовчуванням з динамічним заголовком.

Ви можете використовувати багаторазовий та настроюваний заголовок / колонтитул.

https://github.com/sourov2008/UITableViewCustomHeaderFooterSection


1

перехід 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, не додайте представлення. У швидкому 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

Швидкий 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
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.