Подтвердить что ты не робот

Неверное значение из UITableView: rowHeight на iOS8

Код, который я использовал для создания прямоугольника (по крайней мере до iOS7), был

CGRect rect = [cTableView frame];
rect.origin.y += [cTableView rowHeight];
searchOverlayView = [[BecomeFirstResponderControl alloc] initWithFrame:rect];

В iOS7, cTableView (экземпляр UITableView) возвращается 44. Тестирование в iOS8 с iPhone 5s возвращает -1.

Почему это происходит? Каков правильный код, который необходимо использовать для того, чтобы мое приложение было обратно совместимо с iOS7?

4b9b3361

Ответ 1

Apple изменила высоту строки по умолчанию в iOS8 на UITableViewAutomaticDimension, которая объявлена ​​как -1. Это означает, что ваш табличный вид настроен для автоматического расчета высоты ячейки.

Вам нужно либо реализовать autoLayout (рекомендуется), либо реализовать новый метод делегирования: heightForRowAtIndexPath. Вот большой вопрос об автоматической компоновке: Использование автоматической компоновки в UITableView для динамических раскладок ячеек и переменных высот строк

Похоже, вы все равно были жестким кодированием 44 (старый по умолчанию), так что вы могли бы просто сделать это (не рекомендуется).

Ответ 2

Это заставило меня бороться часами. Я закончил жестко кодировать значение до 44:

self.tableView.rowHeight = 44;

Ответ 3

Существует ограничение производительности для реализации heightForRowAtIndexPath, которое я предпочитаю не выполнять, когда все строки в таблице имеют одинаковую высоту и никогда не изменяются во время выполнения (она вызывается один раз для каждой строки, каждый раз, когда отображается таблица).

В этой ситуации я продолжаю устанавливать "Высота строки" в XIB и использовать следующий дружественный код iOS 8, когда мне нужен rowHeight (он работает и на iOS 7 и ниже).

NSInteger aRowHeight = self.tableView.rowHeight;
if (-1 == aRowHeight)
{
    aRowHeight = 44;
}

Это позволяет вам свободно редактировать высоту строки в XIB и работать, даже если Apple исправляет эту ошибку/функцию в будущем, а XIB устанавливает Row Height = 44 stop возвращается в -1.

Ответ 4

Если вы случайно изменили высоту строки в IB с 44 на что-то еще (например, 40), автоматическое вычисление размера ячейки не выполняется. Ты должен мне 3 часа, Apple.

Ответ 5

Еще одно соображение состоит в том, что если вы вычисляете высоту на основе существующих размеров представления, метод heightForRowAtIndexPath может быть вызван до viewDidLayoutSubviews.

В этом случае переопределите viewDidLayoutSubviews и пересчитайте значение frame.size.height для всех видимых ячеек.

Ответ 6

Мое решение этой проблемы:

@interface MCDummyTableView () <UITableViewDataSource, UITableViewDelegate>
@end

@implementation MCDummyTableView

    - (instancetype) initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
        frame = (CGRect){ 0, 0, 100, 100 };

        self = [super initWithFrame:frame style:style];
        if(!self) return self;

        self.dataSource = self;
        self.delegate = self;

        [self registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CELL"];

        return self;
    }

    - (NSInteger) numberOfSections {
        return 1;
    }

    - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 1;
    }

    - (UITableViewCell*) cellForRowAtIndexPath:(NSIndexPath*)indexPath {
        /*
            UITableView doesn't want to generate cells until it in the view hiearchy, this fixes that.
            However, if this breaks (or you don't like it) you can always add your UITableView to a UIWindow, then destroy it
            (that is likely the safer solution).
        */

        return [self.dataSource tableView:self cellForRowAtIndexPath:indexPath];
    }

    - (UITableViewCell*) tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
        return [self dequeueReusableCellWithIdentifier:@"CELL"];
    }

    - (CGFloat) defaultRowHeight {
        return [self cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]].frame.size.height;
    }

@end

Мне действительно не нравятся жесткие коды. Я использую этот класс для кэширования высоты ячейки по умолчанию в начале приложения.