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

Перемещение элементов управления при изменении ориентации

Я знаю, что Auto Layout может использоваться для согласования размеров и положения при изменении ориентации. Возможно ли полностью изменить макет при изменении ориентации?

Например, просмотрите нижнюю проводную рамку простого экрана входа в портретный режим.

enter image description here

Теперь, если я поворачиваю устройство, я хочу полностью переставить элементы управления.

enter image description here

Можно ли это сделать, используя Auto Layout? Если нет, как мне это сделать?

Спасибо.

4b9b3361

Ответ 1

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

  • Родительский просмотр → Просмотр информации о пользователе → Все элементы информации о пользователе. При этом вам нужно просто пересмотреть представление сведений о пользователе не все элементы управления.

    Затем осталось только имя логотипа и компании, чтобы пересмотреть.. Всего 3 элемента управления для перераспределения, если вы группируете свои элементы управления.

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

Надежда выше помогает.

Ответ 2

вы не можете установить разные рамки: -

-(void)setFramesForPotrait
{

// set frames here

}

-(void)setFramesForLandscaeMode
{

// set frames here

}

-(bool)shouldAutorotate.....
{
return Yes
}

-()willAutoRotate......
{
if(orientation = uiinterfaceOrientationPotrait)
{
[self setFramesForPotrait];
}
else
{
[self setFramesForLandscape];
}

Ответ 3

У меня была такая же проблема, и вот что я нашел до сих пор. Подход, который я использую, имеет два набора (потенциально несколько) наборов ограничений для разных размеров экрана или ориентации. Поэтому я просто создаю портреты и свяжу все ограничения, характерные для портрета IBOutletCollection: enter image description here Затем переключите ориентацию VC в InterfaceBuilder на Landscape и добавьте необходимые ограничения для этой ориентации и подключитесь к соответствующей розетке: enter image description here

Затем в коде я удаляю или добавляю ограничения по мере необходимости:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [self updateViewConstraints];
}

- (void)updateViewConstraints
{
    [super updateViewConstraints];
    if (self.view.frame.size.width >= kSize * 2 + kPadding * 3)
    {
        [self.view removeConstraints:self.constraintsForPortrait];
        [self.view addConstraints:self.constraintsForLandscape];
    } else
    {
        [self.view removeConstraints:self.constraintsForLandscape];
        [self.view addConstraints:self.constraintsForPortrait];
    }
}

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

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [self updateViewConstraints];
}

Но имея в виду, что Apple, по слухам, выпускает устройства с различными пропорциями экрана и исключает события UIInterfaceOrientation и ротации, возможно, стоит заранее подготовиться. Посмотрите, какое будущее приносит.

Недостатком подхода является то, что Xcode будет жаловаться на то, что дизайн является неоднозначным, что на самом деле происходит, поскольку Xcode не знает, что мы будем устранять неоднозначность во время выполнения. Чтобы решить, что вы можете установить приоритет ограничений как необязательный для всех других ориентаций, которые вы не планируете в этот конкретный момент (например, если вы проектируете для Portrait, а затем опционально ограничиваете ограничения для Landscape).

Ответ 4

При использовании автозапуска вы можете переопределить updateViewConstraints, чтобы изменить макет при изменении ориентации:

- (void)updateViewConstraints{

  [super updateViewConstraints];
  //portrait
  if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){

  }
  //landscape
  else{
    //
  }
}

Ответ 5

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

@implementation ViewController {
    IBOutlet NSLayoutConstraint *buttonWidth;
    IBOutlet NSLayoutConstraint *logoTop;
    IBOutlet NSLayoutConstraint *logoAlignToLabel;
    IBOutlet NSLayoutConstraint *logoSpaceToLabel;
    IBOutlet NSLayoutConstraint *coNameToButtonAlignment;
    IBOutlet UIButton *b;
    IBOutlet UIImageView *logo;
    IBOutlet UILabel *coName;
    NSLayoutConstraint *con2;
    NSArray *cons1;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [b removeConstraint:buttonWidth];
    buttonWidth = [NSLayoutConstraint constraintWithItem:b attribute:NSLayoutAttributeWidth relatedBy:0 toItem:self.view attribute:NSLayoutAttributeWidth multiplier:-.2193 constant:350];
    [self.view addConstraint:buttonWidth];
    [self.view layoutSubviews];
}

- (void)updateViewConstraints{
    [super updateViewConstraints];
    if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
        if (con2 != nil) {
            [self.view removeConstraints:cons1];
            [self.view removeConstraint:con2];
            [self.view addConstraints:@[logoAlignToLabel,logoSpaceToLabel,logoTop,coNameToButtonAlignment]];
        }
    }else{
        NSLog(@"Landscape");
        [self.view removeConstraints:@[logoAlignToLabel,logoSpaceToLabel,logoTop,coNameToButtonAlignment]];
        cons1 = [NSLayoutConstraint constraintsWithVisualFormat:@"|-8-[logo]-4-[coName]" options:NSLayoutFormatAlignAllCenterY metrics:0 views:@{@"logo":logo, @"coName":coName}];
        con2 = [NSLayoutConstraint constraintWithItem:logo attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
        [self.view addConstraints:cons1];
        [self.view addConstraint:con2];
    }
}

Во время ротации логотип и название фирменного наименования устраняются, а новые устанавливаются на место. Новое ограничение для кнопки, которую я вставляю в viewDidLoad, автоматически заботится о ротации, поэтому мне не нужно настраивать ее вообще во время вращения.