Различные раскладки в портретном и ландшафтном режиме

предположим, у меня есть этот дизайн макета на портрете iPad.

Screen1

но я хотел бы, чтобы он таким образом, когда iPad находится в горизонтальном: screen2

можно ли это сделать с помощью Auto layout? Или с небольшим количеством кода?

7 ответов


Примечание-ответы здесь хороши и решают проблему, но в более старых версиях iOS.

для iOS11 (Xcode 9) вы должны рассмотреть Адаптивные Макеты как указано здесь: https://www.raywenderlich.com/162311/adaptive-layout-tutorial-ios-11-getting-started


вы можете добиться этого с помощью кода прежде всего вы должны сделать IBoutlet ваших динамических ограничений

Постоянное Ограничение: // эти ограничения останутся одинаковыми в обоих направлениях

1-RedView верхнее пространство для просмотра

2-Redview трейлинг пространство для просмотра

3 - BlueView ведущее пространство для просмотра

4-нижнее пространство BlueView для просмотра

Динамическое Ограничение

Портрет Ограничение:

1 - высота RedView

2 - RedView вертикальное пространство для BlueView

3 - RedView ведущее пространство для просмотра

4 - BlueView трейлинг-пространство для Суперпанель

Пейзаж Ограничения:

1 - Ширина RedView

2 - RedView горизонтальное пространство для BlueView

3-RedView нижнее пространство для Superview

4-BlueView топ пространство для просмотра

теперь вам нужно переопределить метод, который вызывается при изменении ориентации

override func viewWillTransitionToSize(size: CGSize,   withTransitionCoordinator coordinator:    UIViewControllerTransitionCoordinator) {

    coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in

        let orient = UIApplication.sharedApplication().statusBarOrientation

        switch orient {
        case .Portrait:
            print("Portrait")
            self.ApplyportraitConstraint()
            break
            // Do something
        default:
            print("LandScape")
            // Do something else
            self.applyLandScapeConstraint()
            break
        }
        }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            print("rotation completed")
    })
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

и назовите эти 2 функции

Функция Портретной Ориентации

func ApplyportraitConstraint(){

 self.view.addConstraint(self.RedViewHeight)
 self.view.addConstraint(self.RedView_VerticalSpace_To_BlueView)
 self.view.addConstraint(self.RedView_LeadingSpace_To_SuperView)
 self.view.addConstraint(self.BlueView_TrailingSpace_To_SuperView)

 self.view.removeConstraint(self.RedViewWidth)
 self.view.removeConstraint(self.RedView_HorizontalSpace_To_BlueView)
 self.view.removeConstraint(self.RedView_BottomSpace_To_SuperView)          
 self.view.removeConstraint(self.BlueView_TopSpace_To_SuperView)


}

Функция Альбомной Ориентации

    func applyLandScapeConstraint(){

    self.view.removeConstraint(self.RedViewHeight)
    self.view.removeConstraint(self.RedView_VerticalSpace_To_BlueView)
    self.view.removeConstraint(self.RedView_LeadingSpace_To_SuperView)
   self.view.removeConstraint(self.BlueView_TrailingSpace_To_SuperView)

    self.view.addConstraint(self.RedViewWidth)
    self.view.addConstraint(self.RedView_HorizontalSpace_To_BlueView)
    self.view.addConstraint(self.RedView_BottomSpace_To_SuperView)
    self.view.addConstraint(self.BlueView_TopSpace_To_SuperView)

}

Портрет Скриншот: enter image description here Ландшафтная Скриншоте: enter image description here

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

Github:

Если у вас есть предупреждения, просто установите приоритет ограничения высоты и ширины на 999.


iPAD не имеет класса размера для ландшафтного режима. Я думаю, причина в том, что это не нужно в большинстве случаев. Однако можно активировать и деактивировать ограничения при изменении ориентации устройства, как принятый ответ.

следующее Может быть полезно для пользователя iPhone.

Да это возможно в interface builder с классами autolayout и size. Вам не нужно будет кодировать.

сначала вы выбираете размер класса wAny Хани!--1-->

здесь Как выбрать размер класса.

enter image description here

добавьте два вида в контроллер вида. Красный вид сверху и синий вид снизу. Как и твой первый образ.

ограничения на красный вид:

  • верхний космос к супер взгляду
  • ведущее пространство для super view
  • Trailing space to super view
  • высота = 50

ограничения на синем фоне находятся:

  • вертикальное пространство для красного вида
  • ведущее пространство для super view
  • trailing space to super view
  • Нижний космос к супер взгляду

Это все настроено для режима Potrait.

теперь вы меняете классы размера на wAny hCompact (первые два столбца в первой строке). этот класс предназначен для ландшафта iPhone.

теперь вы должны использовать установить и удалить концепции.

ограничения, которые будут меняться для red view:

  • удалите его высоту constriant для (wAny hCompact) размер класса как:

enter image description here

  • Similary удалите его ведущее ограничение. Добавьте два новых ограничения к этому красному представлению в этом классе:
  • нижнее пространство для просмотра
  • ограничение ширины = 50

Это сделайте красный вид на правую сторону с шириной 50.

теперь изменение ограничения для blue view:

  • удалить ее вертикальный отступ, пробел.

добавить два новых ограничения:

  • вертикальное пространство для super view
  • Trailing space to red View

Это прикрепит красный вид слева от синего вида.

надеюсь, это сработает для вас.


можно ли это сделать с помощью Auto layout? Или с небольшим количеством кода?

вам нужно будет сделать оба эти макета для iPad.

  1. определите ограничения компоновки для каждого вида, не устанавливайте ограничения ширины или высоты для этих видов.
  2. провод до IBOutlets для каждого ограничения на просмотр один и два.
  3. реализовать протокол UIContentContainer в вашем представлении контроллер.

    viewWillTransitionToSize(_ size: CGSize,withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)

Обсуждение UIKit вызывает этот метод перед изменением размера a представлен вид контроллера вида. Этот метод можно переопределить в собственные объекты и использовать его для выполнения дополнительных задач, связанных с размером изменение. Например, контроллер представления контейнера может использовать этот метод переопределение признаков встроенных контроллеров дочерних представлений. Используйте предоставленный координатором объект анимировать любые изменения.

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

- Это метод, который вам нужно реализовать. Внутри этого метод вам нужно будет проверить свойства размера ширина и высота, чтобы выяснить, как ваш макет должен измениться - т. е. ландшафтный или портретный макет. Обратите внимание, что этот метод говорит, что это будет изменить на пройденный размер.

  1. отрегулируйте ограничения на основе, если устройство будет вращаться на портрет или пейзаж.

я реализовал это с помощью Obj-C и опубликовал на мой github Решение включает в себя небольшое количество кода, и большая часть работы сосредоточена на Autolayout и соглашениях об именах... Файл README объясняет, как я это сделал. Код, который я использовал на ViewController, в основном это метод:

- (void)setUpViewConstraintsForInterfaceOrientation:(InterfaceOrientation)interfaceOrientation {
    self.lastOrientation = interfaceOrientation;
    if (interfaceOrientation == Landscape) {
        [NSLayoutConstraint deactivateConstraints:self.portraitConstraintsCollection];
        [NSLayoutConstraint activateConstraints:self.landscapeConstraintsCollection];
    } else if(interfaceOrientation == Portrait){
        [NSLayoutConstraint deactivateConstraints:self.landscapeConstraintsCollection];
        [NSLayoutConstraint activateConstraints:self.portraitConstraintsCollection];
    }
    [self.view layoutIfNeeded];
}

portraitConstraintsCollection и landscapeConstraintsCollection-это свойства IBOutletCollection для управления конкретной ориентацией ограничения.

и решение autolayout работает только с установкой и удалением ограничений (активировать и деактивировать), нет необходимости добавлять или удалять ограничения.


моя задача была аналогичной в целом. Мне нужны были портретные и ландшафтные ограничения для iPhone и iPad. Кроме того, расположение желтых и серых видов должно быть одинаковым в целом, но ширина желтого вида должна отличаться в ландшафте iPhone и в ландшафте iPad (40% экрана в iPhone и 60% экрана в iPad): enter image description here

ограничения для ориентаций iPhone я установил, используя коллекции признаков и определяя для каждого ограничения, для чего коллекция должна быть установлена. Для iPhone есть wChR (портрет) и wChC (пейзаж). Или wC с Хани:

enter image description here

но для альбомной и портретной ориентации на iPad используются коллекции отдельных признаков (wRhR), поэтому способ, используемый для iPhone, не подходит. Чтобы изменить ограничения для этих случаев, я создаю два набора ограничений (первый для iPad в ландшафте и второй для iPad в портрет):

@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *ipadLandscapeConstraints;
@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *ipadPortraitConstraints;

Примечание.: 1. Для этого выберите несколько необходимых ограничений в раскадровке и подключите их к вашему .m-файл. Чтобы узнать, какие ограничения были добавлены в массив, нажмите кнопку"+", чтобы оставить свойство.m-файл: enter image description here 2. Я использовал приоритет ограничений для решения конфликтов ограничений для iPad

наконец, я реализовал configConstraints метод переключения наборов ограничений в соответствии с ориентацией iPad и переопределен viewWillTransitionToSize способ:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [self configConstraints];
}

- (void)configConstraints {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        // iPad landscape orientation
        if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
            [NSLayoutConstraint deactivateConstraints:self.ipadPortraitConstraints];
            [NSLayoutConstraint activateConstraints:self.ipadLandscapeConstraints];
        }
        // iPad portrait orientation
        else {
            [NSLayoutConstraint deactivateConstraints:self.ipadLandscapeConstraints];
            [NSLayoutConstraint activateConstraints:self.ipadPortraitConstraints];
        }
        [self.view layoutIfNeeded];
    }
}

может быть, потребуется позвонить configConstraints метод в других местах, где посмотреть загрузки или появляется, но базовая идея описана выше.


гораздо проще поместить эти два вида в представление стека и изменить ориентацию оси для stackview.

  1. создайте ссылку IBOulet на stackview
  2. реализовать viewWillTransitionToSize
  3. измените ось для каждой ориентации путем делать собственную личность.stackView.ось. = вертикаль или. горизонтально