Обновление кадра UILabel подкласса в setText: поскольку UILabel не изменяет размер в UITableViewCell до перезагрузки ячейки

Я создал подкласс UILabel, который собираюсь использовать во многих разных UITableViewCell.

В пределах setText: я использовал sizeWithFont, чтобы получить динамическую высоту для UILabel.

Все это прекрасно работает, однако рамка подкласса UILabel не меняется, пока ячейка не будет перерисована. Как мне преодолеть это?

Примечание. В приведенном ниже коде размер не изменится при перерисовке из-за оператора if. Я взял это для тестирования и обнаружил, что это работает после перерисовки.

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

Вот код, который я использую:

- (void)setText:(NSString *)text
{
    if (text != _text) {
        //  Adjust size to fit contents
        //
        CGSize maximumSize = CGSizeMake(CGRectGetWidth(self.frame), CGFLOAT_MAX);
        CGSize predictedSize = [text sizeWithFont:self.font constrainedToSize:maximumSize lineBreakMode:self.lineBreakMode];

        NSLog(@"Predicted size for \"%@\" (width: %f) is %@", text, self.frame.size.width, NSStringFromCGSize(predictedSize));

        CGRect headlineDescriptionLabelFrame = self.frame;

        headlineDescriptionLabelFrame.size = predictedSize;

        NSLog(@"Old frame: %@", NSStringFromCGRect(self.frame));

        [self setFrame:headlineDescriptionLabelFrame];

        NSLog(@"New frame: %@", NSStringFromCGRect(self.frame));

        _text = text;
    }
}

Мой вывод выглядит так (с отключенным выше «если»):

2012-12-19 19:51:23.576 myApp[1099:c07] Predicted size for "Facebook's photo-sharing service Instagram denies that it has changed its privacy policy to allow it to sell users' photos to advertisers." (width: 172.000000) is {170, 75}
2012-12-19 19:51:23.578 myApp[1099:c07] Old frame: {{138, 46}, {172, 49}}
2012-12-19 19:51:23.578 myApp[1099:c07] New frame: {{138, 46}, {170, 75}}

Ячейка перезагружается здесь
UILabel изменяется и отображается после этой первой перезагрузки ячейки

2012-12-19 19:51:30.018 myApp[1099:c07] Predicted size for "Facebook's photo-sharing service Instagram denies that it has changed its privacy policy to allow it to sell users' photos to advertisers." (width: 172.000000) is {170, 75}
2012-12-19 19:51:30.018 myApp[1099:c07] Old frame: {{138, 46}, {172, 49}}
2012-12-19 19:51:30.019 myApp[1099:c07] New frame: {{138, 46}, {170, 75}}

Обновить ячейку здесь

2012-12-19 19:51:32.014 myApp[1099:c07] Predicted size for "Facebook's photo-sharing service Instagram denies that it has changed its privacy policy to allow it to sell users' photos to advertisers." (width: 170.000000) is {170, 75}
2012-12-19 19:51:32.014 myApp[1099:c07] Old frame: {{138, 46}, {170, 75}}
2012-12-19 19:51:32.015 myApp[1099:c07] New frame: {{138, 46}, {170, 75}}

ИЗМЕНИТЬ

После 4 дней попыток выяснить это, у меня все еще есть проблемы с этим, кто-нибудь знает, является ли это ошибкой на стороне Apple? Как другие люди изменяют размер UILabel, загруженного из пера UITableViewCell, внутри cellForRowAtIndexPath:?


person Adam Carter    schedule 19.12.2012    source источник
comment
Вы пробовали с setNeedsLayout ?   -  person Cyrille    schedule 20.12.2012
comment
Да все равно та же проблема   -  person Adam Carter    schedule 20.12.2012
comment
Можно ли как-то "поднять" этот вопрос, я нигде не могу найти, как решить проблему   -  person Adam Carter    schedule 20.12.2012
comment
Кроме того, я создал UITableViewCell в Interface Builder. Начальная высота — та, которая используется в IB, затем, когда ячейка перерисовывается обратно на экран, отображается правильная высота, хотя ее рамка говорит, что изначально была установлена ​​​​правильная высота.   -  person Adam Carter    schedule 20.12.2012
comment
Как выглядит ваш tableView:heightForRowAtIndexPath:?   -  person Cyrille    schedule 21.12.2012
comment
Он возвращает число с плавающей запятой '130.0f' (это высота ячейки, которая достаточно велика, чтобы вместить все содержимое ячеек)   -  person Adam Carter    schedule 21.12.2012


Ответы (2)


Вместо «перезагрузить ячейку здесь» просто попробуйте

[tableView beginUpdates];
[tableView endUpdates];

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

person Cyrille    schedule 21.12.2012
comment
Спасибо за ответ, мои ячейки «перезагружаются», когда я прокручиваю tableView не с помощью кода. Если бы я реализовал ваш код, где бы его лучше разместить? - person Adam Carter; 22.12.2012
comment
Как я уже сказал, вместо cell reload here в коде вы вставили. - person Cyrille; 22.12.2012
comment
Вы имеете в виду метод setText:? Это не работает. Н.Б. Код, который я вставил выше с Cell reload here, выводится из журнала - person Adam Carter; 22.12.2012

Оказывается, все, что мне нужно было сделать, это добавить код смены кадра в layoutSubviews (а также суперметод [super layoutSubviews].

person Adam Carter    schedule 28.12.2012