UITableViewHeaderFooterView с IB

После многих лет избегания Interface Builder, как чумы, я решил дать ему шанс. Это нелегко.

Возьмите UITableViewHeaderFooterView, например. Как UITableViewCell, он имеет свойство contentView. В отличие от UITableViewCell, он не имеет шаблона в библиотеке объектов Interface Builder.

Как мы должны использовать Interface Builder для создания UITableViewHeaderFooterView с содержимым внутри contentView? Тот факт, что registerNib:forHeaderFooterViewReuseIdentifier: существует, заставляет меня думать, что это должно быть возможно как-то.

Ответ 1

Это ближайший я определил UITableViewHeaderFooterView с IB:

а. Создайте подкласс UITableViewHeaderFooterView (MYTableViewHeaderFooterView).

б. Создайте файл nib только для contentView (MYTableViewHeaderFooterContentView).

с. Переопределите initWithReuseIdentifier: в MYTableViewHeaderFooterView, чтобы загрузить представление, определенное в файле nib.

 - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithReuseIdentifier:reuseIdentifier];
    if (self)
    {
        NSArray* objects = [[NSBundle mainBundle] loadNibNamed:@"MYTableViewHeaderFooterView"
                                                          owner:self
                                                        options:nil];
        UIView *nibView = [objects firstObject];
        UIView *contentView = self.contentView;
        CGSize contentViewSize = contentView.frame.size;
        nibView.frame = CGRectMake(0, 0, contentViewSize.width, contentViewSize.height);
        [contentView addSubview:nibView];
    }
    return self;
}

д. Зарегистрируйте класс MYTableViewHeaderFooterView вместо файла nib:

[self.tableView registerClass:[MYTableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"cell"];

Ответ 2

Я просто сделал это с нижним колонтитулом и файлом NIB:

  • Создайте пустой файл NIB с именем CustomFooterView.xib.
  • Отредактируйте файл NIB в построителе интерфейса и измените самый верхний пользовательский класс UIView на UITableViewHeaderFooterView.
  • Отключить автоматическую компоновку в NIB.
  • Установите цвет фона UITableViewHeaderFooterView для просмотра по умолчанию.
  • Сделайте вид свободной формы и правильный размер (например, 320 x 44).
  • В вашем UITableViewController viewDidLoad зарегистрируйте файл NIB, который будет использоваться с идентификатором повторного использования:

    [self.tableView registerNib:[UINib nibWithNibName:@"CustomFooterView" bundle:nil] forHeaderFooterViewReuseIdentifier:@"Footer"];
    
  • В UITableViewController tableView:viewForFooterInSection: используйте идентификатор нижнего колонтитула для извлечения и возврата представления:

    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
    {
        if (section == 2)
            return [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Footer"];
    
        return nil; 
    }
    

Ответ 3

Просто используйте шаблон UITableViewCell в IB. Измените класс на UITableViewHeaderFooterView. Здесь у вас есть... с contentView.

Ответ 4

Я нашел более простой способ.

1) Создайте подкласс UITableViewCell и установите xib файл

2) В вашем файле заголовка измените суперкласс с UITableViewCell на UITableViewHeaderFooterView

Что это.

Ответ 5

Это решение работает хорошо, особенно если вы хотите, чтобы он работал правильно в отношении Readable Content Guides (представленный в iOS 9). Вместо создания UITableViewHeaderFooterView он просто возвращает пользовательский UIView (из XIB), когда это необходимо:

  • Создайте новый класс, который подклассифицирует UIView ( "AwesomeHeaderView" ) и создаст ваши точки:

    class AwesomeHeaderView: UIView {
        @IBOutlet var myCustomLabel: UILabel!
    }
    
  • Создайте файл XIB ( "MyNewHeader.xib" ) с UIView как родительский вид. Измените родительский тип класса UIView на новый созданный пользовательский класс ( "AwesomeHeaderView" ). При необходимости добавьте любые дополнительные представления в виде дочерних элементов и ссылок и т.д. (Примечание: чтобы представления соответствовали новым рекомендациям для читаемого содержимого, я проверяю флажки "Сохранять поля надзора" и "Следуйте за удобочитаемой шириной" на всех объектах).
  • В вашем UIViewController (или UITableViewController) вызывает следующее:

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        guard let headerView = NSBundle.mainBundle().loadNibNamed("MyNewHeader", owner: nil, options: nil).first as? AwesomeHeaderView else {
            return nil
        }
    
        // configure header as normal
        headerView.backgroundColor = UIColor.redColor()
        headerView.myCustomLabel.textColor = UIColor.whiteColor()
        headerView.myCustomLabel.text = "Hello"
    
        return header
    }
    

Ответ 6

Последующие обходные пути позволяют мне перетаскивать элементы IB для кодирования в качестве переменных. UITableViewHeaderFooterView не позволяет это из коробки.

  • создать (Новый файл /CocoaTouchClass ) UITableViewHeaderFooterView .h.m.xib обычно

  • временно переименовать суперкласс из UITableViewHeaderFooterView в UIView. Перетащите назначьте свои элементы пользовательского интерфейса в соответствии с требованиями, IB назначит значение ключа правильно, вернитесь обратно в UITableViewHeaderFooterView, когда закончите.

  • в вашем представлении таблицы используйте registerNib: для регистрации вместо registerClass:. обычно подготовьте остальную часть таблицы (т.е.: dequeue).

Ответ 7

Ужасный хак, который я понял, заключается в том, чтобы создать IBOutlet contentView ih ваш класс headerFooter и подключить его к вашему "представлению содержимого" в xib (выложите свой xib как tableViewCell, View- > contentView- > mystuff).

Вы получите предупреждения, хорошо готовы к взлому...

Удалите IBOutlet, и все будет работать.

Ответ 8

Я также испытал предупреждение об устаревании выше и неспособность установить цвет фона и т.д. В конце концов, я обнаружил, что согласно документации Apple,

В большинстве случаев вы можете использовать [UITableViewHeaderFooter] класс as-is без подкласса. Если у вас есть настраиваемый контент для отображения, создайте субвью для своего контента и добавьте их в представление в свойстве contentView.

Следуя этому предложению, я сделал следующие шаги:

  • Я создал xib с представлением, которое расширяет только UIView - не UITableViewHeaderFooter.
  • В viewDidLoad я зарегистрировал встроенный класс UITableViewHeaderFooter

    tableView.registerClass(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "sectionHeader" )

  • В делегате viewForHeaderInSection моего UITableViewController я удалил представление заголовка этим идентификатором и проверил, не видит ли в представлении заголовка подвью. Если нет, я загружаю свой xib и добавляю его. Затем я установил свой текст по мере необходимости.

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("sectionHeader")!
    
    if header.contentView.subviews.count == 0 { header.contentView.addSubview(loadMyNib()) }
    
    let myView = header.contentView.subviews[0] as! MyView
    myView.label.text = "..."
    

Это похоже на работу, использует повторное использование и не вызывает никаких предупреждений.

https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UITableViewHeaderFooterView_class/index.html#//apple_ref/occ/instm/UITableViewHeaderFooterView/prepareForReuse