UIButton titleLabel размер кадра, возвращающий CGSize с нулевой шириной и высотой
Для iOS7 я использовал свойство UIButton
titleLabel.frame.size.width
для определения ширины названия моей кнопки в разных локализации, чтобы я мог правильно позиционировать заголовок, используя contentInset
на UIButton
.
My UIButton
настроен с изображением и названием, и я всегда хочу, чтобы комбинация этих двух была горизонтально сосредоточена в UIButton
, например:
[space-x (image) space-y (titleLabel) space-x]
В iOS 7 и Xcode 5.1 следующий код работает отлично (даже работает на iOS 8 GM при построении в XCode 5.1):
CGSize buttonSize = button.frame.size;
CGSize titleSize = button.titleLabel.frame.size;
float contentInset =((buttonSize.width - (titleSize.width + 18 + 3)) / 2 );
float contentInsetRounded = roundf(contentInset);
[button setContentEdgeInsets:(UIEdgeInsetsMake(0, contentInsetRounded, 0, 0))];
(18 - ширина изображения, а 3 - количество интервалов между изображением и titleLabel
или пробел-y в моем примере выше)
В iOS 8 и Xcode 6 GM button.titleLabel.frame.size
возвращает CGSize
с нулевой шириной и высотой, поэтому мой ContentInset заканчивает центрирование UIImage
в UIButton
, заставляя titleLabel
усекать.
Любые идеи? Я попытался установить текст titleLabel
непосредственно перед этим кодом, если он считает, что он пуст, но это тоже не помогло.
Спасибо заранее!
Ответы
Ответ 1
I разрешено. Приложение запускается на iOS8, создается с помощью Xcode 6, а не обновляет кадр сразу после UIButton setTitle
, setTitleEdgeInsets
. Он будет ждать следующего обновления пользовательского интерфейса. Итак, если вы получаете фреймворк titleLabel, вы получите CGRectZero.
Решение
-
Вызовите ниже методы после установки свойства пользовательского интерфейса, чтобы немедленно обновить макет:
[self setNeedsLayout];
[self layoutIfNeeded];
Или:
- Задержка секунды, и вы можете получить
titleFrame
, использовать self.titleLabel.frame
.
Или:
- dispatch_async в главной очереди, чтобы переместить код в следующую очередь
Ответ 2
Задайте текст заголовка, затем сделайте sizeToFit для ярлыка заголовка и попробуйте получить названиеLabel.frame.size.width
[myButton setTitle:@"My Title" forState:UIControlStateNormal];
[myButton.titleLabel sizeToFit];
Ответ 3
Если после установки кадра вы устанавливаете изображение рядом с кнопкой, вы можете использовать
[theButton setTitle: @"theTitle" forState:UIControlStateNormal];
[theButton setImage: theImage forState:UIControlStateNormal];
[theButton setNeedsLayout];
[theButton layoutIfNeeded];
[theButton setImageEdgeInsets: UIEdgeInsetsMake(6, transactionsButton.titleLabel.frame.size.width + 40.0, 0, 0)];
И в Swift 3 это будет делать.
self.view.layoutIfNeeded()
Ответ 4
Возможно, это не сработает для вас, но у меня была такая же проблема при запуске моего кода в XCode 6 GM/iOS8 и не удалось заставить его работать. Он работал случайным образом, и в итоге я использовал другой подход вместо NSString. Я использовал NSAttributedString в качестве заголовка.
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:@"Button text"];
NSTextAttachment* textAttachment = [NSTextAttachment new];
textAttachment.image = [UIImage imageNamed:@"Arrows"];
NSAttributedString *finalString = [NSAttributedString attributedStringWithAttachment:textAttachment];
[attributedText appendAttributedString:finalString];
Только остерегайтесь того, что его iOS7 и выше, но, похоже, работают безупречно.
Ответ 5
Оказывается, я сильно передумал в этой проблеме. Я достал весь код кода содержимого, поэтому мне не нужно было найти frame.size. Теперь я просто центризую названия кнопок, и все хорошо!
Кажется, что есть проблема с получением frame.size, но для моих нужд я могу обойти это.