Выделение и определение размеров подсмотров в UIViewController

У меня есть приложение с UITabController, и каждая вкладка UINavigationController. Корнем одного из моих UINavigationControllers является UIViewController.

Внутри этого вида контроллера контроллера я хочу разбить некоторые подвидные объекты, но я смущен относительно того, где и как их выкладывать таким образом, что это будет независимым от разрешения (т.е. не такими значениями hardcode, как 320px, 480px, 44px и т.д.).

Когда представление полностью загружено и представлено на вертикальном iPhone, высота будет 367px = 480 - 20 (строка состояния) - 44 (панель навигации) - 49 (панель вкладок).

Внутри контроллера представления я в настоящее время создаю все мои подпрограммы в методе viewDidLoad. Однако, похоже, что в этом методе высота текущего представления составляет 460 пикселей (self.view.bounds.size.height). Поэтому при настройке моих подпрограмм я не могу правильно рассчитать размеры чего-либо.

В методе viewWillAppear: представление знает его надлежащий размер, но это будет означать настройку и вычисление кадров subview каждый раз, когда появится представление (например, изменения вкладок или выскакивание из дочернего представления контроллеров в стеке навигации.

Это единственный способ сделать это правильно для макета в viewWillAppear:?

Я попытался использовать свойства авторазрешения (parent autoresizesSubviews и autoresizingMask), но они вообще не работают!? Вступают ли они в силу только после того, как все настройки настроены, а затем изменены (изменение вручную/ориентация?).

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

Ответ 1

autoresizesSubviews должен быть установлен в вашем родительском представлении, а autoresizingMask должен быть установлен на дочерние представления - это ошибка, которую я сделал так, чтобы вы тоже.

В loadView вам следует настроить размер ваших подзонов, чтобы он соответствовал любому размеру родительского представления, а затем, когда размер родительского представления будет изменен с 460 до 367 пикселей, ваши подвидки также будут изменены, согласно ваши настройки маски выше.

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

Если ничего не работает, всегда есть layoutSubviews: - там вы можете сделать макет вручную, если это необходимо, оно вызывается, когда система считает, что макет может измениться. существует также setNeedsLayout: иногда я вызываю из viewWillRotate:/viewDidRotate: и т.д. Но на самом деле это не нужно, а авторейтизация должна быть достаточно хорошей.

EDIT: Да, для реализации пользовательской логики макета в layoutSubviews, как я упоминал выше, нужно было бы подклассом UIView.

Ответ 2

Вы можете выполнить свою логику компоновки внутри viewWillLayoutSubviews UIViewController.

-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    // Your layout logic here
}

DOC: Вызывается непосредственно перед представлением диспетчера представлений layoutSubviews метод вызывается. Подклассы могут реализовываться по мере необходимости. По умолчанию используется nop.