Автомакет и ограничения для iPad

Я совершенно запутался в новой функции автоматической компоновки xCode 4.5.

Вот я хочу сделать,

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

Используя автомакет и ограничения (и булавки), как я могу преобразовать макет, когда он перевернут в альбомную ориентацию? введите здесь описание изображения

Я пробовал кодировать и изменять CGRect (размер и координаты) представлений, когда он ландшафтный, но безрезультатно.


person ruelluna    schedule 24.05.2013    source источник


Ответы (2)


NSLayoutConstraints заменяет потребность в CGRects в Auto Layout. Во-первых, опишите свой макет словами. Вот как я бы описал ваш пример портрета:

  • Ширина красного составляет 60% от его супервида.
  • Высота синего составляет 55% от его супервида.
  • Левый и правый края синего касаются его супервида.
  • Левый край красного цвета касается его супервида, правый край красного близок к левому краю желтого, а правый край желтого касается его супервида.
  • Верхний край синего цвета касается его супервида, нижний край синего близок к верхнему краю красного, а нижний край красного цвета касается его супервида.
  • Нижний край синего близок к верхнему краю желтого, а нижний край желтого касается его супервида.

Вот метод, который удаляет существующие ограничения superview, а затем применяет новые ограничения для заданной ориентации интерфейса.

- (void) buildConstriantsForInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Remove existing constraints.
    [superview removeConstraints:superview.constraints] ;
    // Build an array to hold new constraints.
    NSMutableArray* constraints = [NSMutableArray new] ;

    // Add 2 constraints that apply to both Portrait & Landscape orientations.
    [constraints addObject:[NSLayoutConstraint constraintWithItem:red  attribute:NSLayoutAttributeWidth  relatedBy:NSLayoutRelationEqual  toItem:superview  attribute:NSLayoutAttributeWidth  multiplier:0.6  constant:0]] ;
    [constraints addObject:[NSLayoutConstraint constraintWithItem:blue  attribute:NSLayoutAttributeHeight  relatedBy:NSLayoutRelationEqual  toItem:superview  attribute:NSLayoutAttributeHeight  multiplier:0.55  constant:0]] ;

    // Build a dictionary to store references to NSViews.
    NSDictionary* views = NSDictionaryOfVariableBindings(superview, blue, red, yellow) ;
    // To eliminate repeated NSLayoutConstraint code, build an array of Format Strings with which to build constraints.
    NSArray* formatStrings ;
    if ( UIInterfaceOrientationIsPortrait(interfaceOrientation) ) {
        formatStrings = @[@"H:|[blue]|", @"H:|[red]-[yellow]|", @"V:|[blue]-[red]|", @"V:[blue]-[yellow]|"] ;
    }
    else {
        formatStrings = @[@"H:|[blue]-[yellow]|", @"H:|[red]-[yellow]", @"V:|[blue]-[red]|", @"V:|[yellow]|"] ;
    }

    for ( NSString* formatString in formatStrings ) {
        [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:formatString  options:0  metrics:nil  views:views]] ;
    }

    // Add the newly created constraints.
    [superview addConstraints:constraints] ;
}

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

-(void) viewDidLoad {
    superview.translatesAutoresizingMaskIntoConstraints = NO ;
    [self buildConstriantsForInterfaceOrientation:self.interfaceOrientation] ;
}

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [self buildConstriantsForInterfaceOrientation:toInterfaceOrientation] ;
}
person John Sauer    schedule 24.05.2013

Автомакет отлично подходит для выражения отношения одного объекта к другому и разрешения конфликтов, но он не имеет встроенных условных понятий. Я думаю, что для вашего макета вам будет проще всего добавлять и удалять ограничения на вращение, проверьте https://developer.apple.com/library/ios/#documentation/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html, чтобы узнать, как их добавить.

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

  • Убедитесь, что синий вид имеет ширину ‹= ширину портретной ориентации и >= минимальную ширину альбомной ориентации.
  • Убедитесь, что красный вид имеет минимальную высоту
  • Исправьте ширину желтого вида и установите высоту >= высоты портрета.
  • Привяжите каждый вид к углу, в котором он всегда будет оставаться (например, закрепите конец и низ к супервиду для желтого цвета).
  • Совместите верхнюю часть желтого вида с синим видом с низким приоритетом
  • Увеличьте сопротивление сжатию содержимого для желтого цвета

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

Это довольно сложно описать в тексте, вот скриншот, показывающий три представления и ограничения между ними. Он не показывает все, но вы можете, по крайней мере, проверить отношения между представлениями: xcode, показывающий ограничения

person James    schedule 24.05.2013