Каков правильный способ вызова [super layoutSubviews]?

Я только что видел в Facebook SDK для iOS, они называют [super layoutSubviews]; в конце, а не в начале метода layoutSubviews. Насколько я знаю, мы всегда должны делать это как первая строка. Это может привести к неожиданному поведению для пользовательского интерфейса?

- (void)layoutSubviews
{
  CGSize size = self.bounds.size;
  CGSize longTitleSize = [self sizeThatFits:size title:[self _longLogInTitle]];
  NSString *title = (longTitleSize.width <= size.width ?
                     [self _longLogInTitle] :
                     [self _shortLogInTitle]);
  if (![title isEqualToString:[self titleForState:UIControlStateNormal]]) {
    [self setTitle:title forState:UIControlStateNormal];
  }

  [super layoutSubviews];
}

Ответ 1

В соответствии с ссылкой на класс UIView,

По умолчанию реализация этого метода ничего не делает на iOS 5.1 и ранее. В противном случае реализация по умолчанию использует любые ограничения, которые вы установили для определения размера и положения любых подзонов.

Таким образом, приложение приложения для SDK в Facebook [super layoutSubviews] в конце их реализации может быть артефактом приложения, которое изначально было создано для версии iOS до iOS 5.1.

Для более поздних версий iOS вы должны называть [super layoutSubviews] в начале вашей реализации. В противном случае суперкласс заменит ваши просмотры после выполнения пользовательского макета, фактически игнорируя реализацию "layoutSubviews()".

Ответ 2

загляните в код, прежде чем [super layoutSubviews], это не о кадре. так что положить его в конце может хорошо работать. Я предполагаю, что кодер должен проверить заголовок и изменить заголовок на основе некоторых правил, он думает, что каждый раз, когда вызывается layoutSubviews, это правильная возможность сделать это, поэтому он помещает код здесь.

Ответ 3

Вам всегда нужно называть [super layoutSubviews] последним, если размер внутреннего содержимого представления будет изменен. Если вы измените заголовок кнопки, размер встроенного содержимого UIButton будет изменен, поэтому последний вызов.

Первый вызов [super layoutSubviews] всегда требуется, поскольку iOS обновляет макет на основе ограничений. Однако технический наиболее правильный способ реализации вашей выборки должен быть:

- (void)layoutSubviews
{
 [super layoutSubviews];
  CGSize size = self.bounds.size;
  CGSize longTitleSize = [self sizeThatFits:size title:[self _longLogInTitle]];
  NSString *title = (longTitleSize.width <= size.width ?
                     [self _longLogInTitle] :
                     [self _shortLogInTitle]);
  if (![title isEqualToString:[self titleForState:UIControlStateNormal]]) {
    [self setTitle:title forState:UIControlStateNormal];
  }

  [super layoutSubviews];
}