Внутренний размер не изменяется при изменении состояния UIButton

У меня есть UIView, содержащий UIButton. UIButton имеет 2 заголовка, установленные для состояний UIControlStateNormal ( "Follow" ) и UIControlStateSelected ( "Следующее" ). Я использую автоматическую компоновку на UIButton, и у нее есть ограничение на определенное расстояние от верхней части супервизора, а другое - на некотором расстоянии от левой части супервизора. Я также использовал "Размер для соответствия содержимому".

Когда я устанавливаю кнопку в выбранном состоянии из кода, заголовок изменяется правильно, но внутренняя ширина UIButton не изменяется, поэтому при изменении с "Follow" на "Follow" текст становится эллипсированным.

self.selected = self.following;

enter image description hereenter image description here

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

NSString *title = (self.following) ? @"Following" : @"Follow"
[self setTitle:title forState:UIControlStateNormal];

enter image description hereenter image description here

Является ли это ошибкой в ​​UIKit? Я бы ожидал, что кнопка изменит свой внутренний размер, чтобы правильно отразить новый размер текста, когда его состояние изменяется, особенно потому, что есть другие вещи, которые я хотел бы изменить, кроме текста для состояний двух кнопок.

Ответ 1

Как отметил Давид Каунт в комментарии, вызов invalidateIntrinsicContentSize приведет к тому, что автозапуск изменит размер кнопки, чтобы она соответствовала новому контенту.

self.selected = self.following;
[self invalidateIntrinsicContentSize];

PS. Дэвид, если вы хотите опубликовать свой коммант в качестве ответа, я удалю свою.

Ответ 2

В своем раскадровке выберите свой UIButton и сверху выберите editor- > size, чтобы он соответствовал размеру содержимого.

РЕДАКТИРОВАТЬ: Попробуйте следующее:

[self.myButton setTitle:@"Following" forState:UIControlStateSelected];
[self.myButton sizeToFit];

Ответ 3

Для меня настройка contentEdgeInsets дала мне единственное надежное решение.

Я использую пользовательские кнопки с фоновыми изображениями. Итак, в картину попадают кусочки. Оказывается, как вы нарезаете изображения, вы также можете повлиять на размер собственного контента! Попробуй это! Итак, я должен был удостовериться, что я одинаково нарезал изображения для разных состояний. Я также использую атрибутированные строки. Решения, размещенные здесь, не помогли мне.

То, что я обнаружил после дня (!) экспериментирования, заключается в том, что установка достаточных значений contentEdgeInsets на кнопке позволяет корректно вести себя, когда названия изменяются с помощью автозапуска. Нет необходимости аннулировать собственный размер содержимого или вызывать любой код макета, если вы это сделаете.

Вы можете либо установить contentEdgeInsets в коде, либо в IB.

self.button.contentEdgeInsets = UIEdgeInsetsMake(10.0, 16.0, 10.0, 16.0);

Я думаю, что код Swift идентичен, за исключением атрибута var.

Apple говорит об этом в документах: "Кнопка использует это свойство для определения intrinsicContentSize и sizeThatFits:.".

enter image description here

Ответ 4

Является ли это ошибкой или просто так, как я, я не знаю, но похоже, что вам придется обойти это - я не думаю, что вы делаете что-то неправильно. Если вы хотите переключаться между выбранными, а не после каждого касания, вы можете сделать что-то вроде этого:

- (IBAction)buttonClick:(UIButton *)sender {
    sender.selected = !sender.selected;
    if (sender.selected) {
        [self.button setTitle:@"Following" forState:UIControlStateNormal];
        //Do whatever else you want to do here for the selected state
    }else{
        [self.button setTitle:@"Follow" forState:UIControlStateNormal];
    }
}