Установка UIButton titleEdgeInsets и imageEdgeInsets медленно с Autolayout - программирование
Подтвердить что ты не робот

Установка UIButton titleEdgeInsets и imageEdgeInsets медленно с Autolayout

У меня есть представление с несколькими кнопками разных размеров. Все они имеют заголовок и изображение. Я хотел иметь изображение сверху, название внизу, в центре. Это отлично работает со следующим кодом:

- (void)centerAlignImageAndTextForButton:(UIButton*)button
{
    CGFloat spacing = 5;
    CGSize imageSize = button.imageView.frame.size;
    button.titleEdgeInsets = UIEdgeInsetsMake(0, -imageSize.width, -(imageSize.height + spacing), 0);
    CGSize titleSize = button.titleLabel.frame.size;
    button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0, 0, -titleSize.width);
}

Тем не менее, я замечаю небольшую паузу перед входом в это представление. Time Profiler in Instruments показывает, что 99% времени, проведенного в viewDidLoad, вызвано вызовом моего метода для кнопок:

283.0ms  -[XViewController viewDidLoad]
282.0ms    -[XViewController centerAlignImageAndTextForButton:]
141.0ms      -[UIButton imageView]
 98.0ms        -[UIView(Hierarchy) layoutBelowIfNeeded]
141.0ms      -[UIButton titleLabel]
103.0ms        -[UIView(Hierarchy) layoutBelowIfNeeded]

Различные объекты, связанные с компоновкой, называются внутри [UIView(Hierarchy) layoutBelowIfNeeded], например [UIView(AdditionalLayoutSupport) recursiveLayoutEngineDidChange] или [NSLayoutConstraint addToEngine].

Я знаю, что можно установить эти вставки в Interface Builder, но не только это утомительная работа (нужно "угадать" ширину текста); приложение также будет локализовано, поэтому вставки, которые подходят для одного языка, не будут для другого, где размер текста отличается (я использую базовую локализацию для раскадровки и файлы .strings вместо дублирования всей раскадровки для каждого языка). Так что для меня это, по-видимому, программирование программ, это путь, но отставание, которое оно вызывает, не очень приемлемо.

Любые мысли о том, как это можно решить?

4b9b3361

Ответ 1

Перемещение всех вызовов centerAlignImageAndTextForButton с viewDidLoad на viewDidLayoutSubviews уменьшает время загрузки с предыдущих 283 миллисекунд до 18 миллисекунд (1 миллисекунды для viewDidLoad и 17 миллисекунгов для viewDidLayoutSubviews).

Однако, я немного озадачен, почему так дорого устанавливать эти вставки из viewDidLoad...

Ответ 2

Имела аналогичную проблему при медленном вызове titleLabel от awakeFromNib в пользовательском подклассе UIButton. Перемещение кода для просмотра контроллера было нежелательным из-за большого количества и/или нетривиального жизненного цикла кнопок. Перемещение кода на layoutSubviews не помогло. В конце концов я переместил код в didMoveToSuperview, и он решил проблему.

- (void)didMoveToSuperview
{
    [super didMoveToSuperview];
    self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
    self.titleLabel.numberOfLines = 2;
    self.titleLabel.textAlignment = NSTextAlignmentCenter;
}