Подтвердить что ты не робот

IOS изменяет ограничения автоматической компоновки, когда устройство вращается

Я хочу изменить ограничения макета, когда устройство вращается. Мой UIViewController состоит из 2 UIViews, в ландшафте они выровнены по горизонтали, и в портрете они выровнены по вертикали.

Он действительно работает, в willAnimateRotationToInterfaceOrientation, я удаляю требуемые ограничения и заменяю их другими, чтобы иметь правильный макет...

Но есть проблемы, во время ротации авто макет начинает нарушать ограничения до вызова willAnimateRotationToInterfaceOrientation, так где же мы хотим заменить наши ограничения при переориентации устройства?

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

4b9b3361

Ответ 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;

     }
}