IOS изменяет ограничения автоматической компоновки, когда устройство вращается
Я хочу изменить ограничения макета, когда устройство вращается.
Мой UIViewController
состоит из 2 UIViews
, в ландшафте они выровнены по горизонтали,
и в портрете они выровнены по вертикали.
Он действительно работает, в willAnimateRotationToInterfaceOrientation
, я удаляю требуемые ограничения и заменяю их другими, чтобы иметь правильный макет...
Но есть проблемы, во время ротации авто макет начинает нарушать ограничения до вызова willAnimateRotationToInterfaceOrientation
, так где же мы хотим заменить наши ограничения при переориентации устройства?
Еще одна проблема - производительность, после нескольких поворотов система не нарушает больше ограничений, но у меня огромное падение производительности, особенно в портретном режиме...
Ответы
Ответ 1
В willRotateToInterfaceOrientation:duration:
отправьте setNeedsUpdateConstraints
на любое представление, которое требует изменения его ограничений.
В качестве альтернативы создайте подкласс UIView
. В вашем подклассе зарегистрируйтесь для получения UIApplicationWillChangeStatusBarOrientationNotification
. Когда вы получите уведомление, отправьте setNeedsUpdateConstraints
.
Это устанавливает флаг needsUpdateConstraints
в представлении. Прежде чем система выполнит макет (отправив layoutSubviews
сообщения), он отправит сообщение updateConstraints
любому представлению с установленным флагом needsUpdateConstraints
. Здесь вы должны изменить свои ограничения. Создайте подкласс UIView
и переопределите updateConstraints
, чтобы обновить ваши ограничения.
Ответ 2
В сообщении Matthijs Hollemans есть очень хорошее объяснение автоматической компоновки и поворотов.
Вы можете найти это здесь:
http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
Обычно вам нужно около 4 ограничений для правильного позиционирования вашего представления. Если мои взгляды имеют постоянный размер, я предпочитаю вышивать высоту и ширину. После этого вы можете использовать ограничения ведущего и верхнего пространства, чтобы делать все, что хотите. Например, вы можете установить IBOutlets для ведущих и верхних ограничений пространства для ваших просмотров:
@interface ViewController : UIViewController {
IBOutlet NSLayoutConstraint *_leadingSpaceConstraint;
IBOutlet NSLayoutConstraint *_topSpaceConstraint;
}
Затем перетащите управление из розетки в ваше ограничение.
Теперь вы можете напрямую изменить ограничение вида из кода:
_leadingSpaceConstraint.constant = NEW_CONSTRAINT_VALUE;
Для фиксации изменений вам необходимо позвонить:
[self.view layoutIfNeeded];
И если вы хотите сделать это анимированным:
[UIView animateWithDuration:0.25
animations:^{
[self.view layoutIfNeeded];
}];
Я думаю, что он будет работать в willAnimateRotationToInterfaceOrientation, потому что вам не нужно нарушать какие-либо ограничения с помощью этого подхода.
Пример:
У вас есть два квадратных изображения в портретной ориентации, один под другим. Например, установите ограничения "ведущее пространство для наблюдения" на 20. Затем установите "верхнее пространство для ограничения супервизора" до 20 для первого просмотра и 120 для второго. Это будет наша настройка по умолчанию.
Затем, после поворота, вам нужно пересчитать свои ограничения. Теперь установите оба верхних ограничения на 20 и ведущие ограничения соответственно на 20 и 120. Затем зафиксируйте изменения с помощью layoutIfNeeded.
Надеюсь, это поможет.
Ответ 3
переопределить -(void) viewWillLayoutSubviews
в UIViewController
, чтобы обновить ваши ограничения, как показано ниже:
-(void) viewWillLayoutSubviews {
switch(self.interfaceorientation)
{
case UIInterfaceOrientationLandscapeLeft:
break;
case UIInterfaceOrientationLandscapeRight:
break;
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
break;
}
}