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

Зачем использовать "viewWithTag" с "dequeueReusableCellWithIdentifier"?

может кто-нибудь объяснить, почему вы должны использовать viewWithTag для получения subviews (например, UILabel и т.д.) из ячейки в dequeueReusableCellWithIdentifier?

Некоторая справочная информация: у меня есть пользовательский UITableViewCell с парой UILabel в нем (я воспроизвел простую версию этого ниже). Эти метки определяются в ассоциированном файле NIB и объявляются с помощью IBOutlet и связаны с классом пользовательского класса ячеек. В tableview dequeueReusableCellWithIdentifier я делаю это:

CustomCell *customCell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"];
if (customCell == nil) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];
    for (id oneObject in nib)
        if ([oneObject isKindOfClass:[CustomCell class]])
            customCell = (CustomCell *)oneObject;
}

customCell.firstLabel.text = @"Hello";
customCell.secondLabel.text = @"World!";

return customCell;

Все работает отлично. Однако из учебников, которые я видел, похоже, что при изменении значений меток я должен делать это вместо:

UILabel *firstLabel = (UILabel *)[customCell.contentView viewWithTag:555];
firstLabel.text = @"Hello";

UILabel *secondLabel = (UILabel *)[customCell.contentView viewWithTag:556];
secondLabel.text = @"World!";

(Значения тегов меток установлены в NIB).

Может кто-нибудь сказать мне, какой метод является предпочтительным и почему?

Спасибо!

4b9b3361

Ответ 1

Я понял, что полезно извлекать элементы, используя "viewWithTag", если элементы были добавлены в ячейку программно (т.е. не определены в NIB и подключены через IBOutlets) - это предотвращает создание нескольких меток и т.д. для каждого экземпляра ячейки.

Ответ 2

viewWithTag: - это просто быстрый и грязный способ вытащить дочерние представления без необходимости устанавливать свойства IBOutlet для родителя или даже без создания подкласса UITableViewCell.

Для очень простых случаев это приемлемое решение, для чего предназначался viewWithTag:. Однако, если вы собираетесь многократно использовать эту ячейку или хотите, чтобы у нее был более удобный для разработчиков интерфейс, тогда вы захотите подкласса и использовать реальные свойства, как в первом примере.

Поэтому используйте viewWithTag:, если это очень простая ячейка, которую вы создали в IB без подкласса и всего лишь с несколькими ярлыками. Используйте подкласс ячейки с реальными свойствами для чего-то более существенного.

Ответ 3

Для меня viewWithTag - это Бог. Прежде всего: обработка всех представлений в цикле, как указано на задании, очень просто. Кроме того, я лично предпочитаю этот путь, потому что, если я посмотрю на код и хочу посмотреть, что происходит с представлением, я просто ищу тэг. Он использовался везде, где обрабатывается вид. Против подхода xib, где вам нужно искать код и xib тоже. Кроме того, если у вас есть внешний вид в xib, вы можете наблюдать за ним. Я нашел много xibs, сделанных другими программистами, которые были ПОЛНЫМИ с большим количеством просмотров. Некоторые скрытые, некоторые за кадром, не могли сказать, что из-за того, что все перекрывалось. В таких случаях я считаю, что xibs плохие. Их читать нелегко. Я предпочитаю все, что сделано в коде.

Но если вы решите работать с тегами, не забывайте избегать жесткого кодирования любого тега. Вместо этого создайте список определений #define, чтобы код был чистым и читаемым.

Ответ 4

Я всегда подключаю subviews к свойствам моего подкласса UITableViewCell через IBOutlets, как вы это делали. Я не могу придумать какой-либо веской причины использовать viewWithTag.

Ответ 5

Из справочника класса UITableViewCell: "Делите делегат таблицы в таблицеView: cellForRowAtIndexPath: всегда должен reset весь контент при повторном использовании ячейки". Держите его простым, очистите представление содержимого. Это не делает никаких предположений о пользовательских классах ячеек, отсутствии трансляции, не проверяет класс:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell != nil)
{
    NSArray* contentSubViews = [cell.contentView subviews];
    for (UIView* viewToRemove in contentSubViews)
    {
        [viewToRemove removeFromSuperview];
    }
}

Ответ 6

viewWithTag: позволяет стиль без создания пользовательского подкласса UITableViewCell.

Вы можете назначить идентификатор тега и повторного использования прототипу UITableViewCell в Interface Builder, а затем удалить и изменить вид с этим тегом в реализации вашего UITableViewController, не создавая собственный класс для этой ячейки или не создавая IBOutlets для подзонов ячеек.

В некоторых случаях простота ячейки делает пользовательский класс похож на излишний. viewWithTag: позволяет добавлять пользовательский текст и изображение в ячейку в Storyboard, а затем устанавливать эти настройки с помощью кода, не добавляя дополнительные файлы классов в ваш проект Xcode.