2015-02-01 2 views
10

При использовании автоматической компоновки в раскадровке есть возможность установить установленное ограничение или нет с помощью флажка «Установлено». Отключение его приведет к тому, что он будет вести себя так, как если бы вы не добавили это ограничение - он не будет иметь никакого эффекта. Вы можете настроить установленное состояние для разных классов размера в Interface Builder, и вы можете изменить это значение программно, установив его свойство active на true или false.Где изменить «установлен» для ограничения автоматической компоновки?

В моем приложении я хочу установить ограничение только в том случае, если устройство находится на портрете - оно должно быть «удалено» при повороте в альбомное. Это можно сделать для iPhones, сняв флажок, установленный для Any Width Compact Height. (Хотя, похоже, это работает не так, потому что это нарушает это ограничение из-за противоречивых ограничений при повороте в ландшафт, когда его даже не нужно устанавливать, но независимо от того, что пользовательский интерфейс всегда выглядит так, как ожидалось.) Но нет способа удалить ограничение для iPad в ландшафте в Interface Builder (это регулярная ширина обычной высоты в обеих ориентациях).

Где находится подходящее место для включения/выключения active для NSLayoutConstraint с при вращении устройства? В каком способе поворота будет изменяться этот статус в результате желаемого поведения - только для портрета? Если этот метод не вызван при запуске приложения, в каком другом методе он должен быть помещен в дополнение к методу вращения?

Я попытался поместить следующий код в viewDidLoad и viewWillTransitionToSize, но это приводит к некоторому неожиданному поведению при работе на IPad:

  • Запуска приложения в ландшафте вызывает ограничение быть активным, несмотря на то, активной был установлен на false, он нарушает ограничение, и пользовательский интерфейс не отображается как ожидалось.
  • Запуск приложения в портретных наборах, действующих на true (он уже был установлен в IB), поэтому он работает как ожидается
  • Запуск приложения в портретном и вращающемся устройство работает с ландшафтом, как и ожидалось, - ограничение установлено на неактивное, оно не прерывает ограничение, пользовательский интерфейс отображается как ожидалось.
  • Запуск приложения в портрете, поворот в сторону пейзажа и обратно к портрету приводит к правильному отображению пользовательского интерфейса, но он ломает это ограничение, которое установлено на активное

Если я удалю ограничение в Interface Builder, тогда запустите указанные выше сценарии, я получаю по существу противоположное поведение.

if size.width > size.height { 
    self.myConstraint.active = false 
} else { 
    self.myConstraint.active = true 
} 

ответ

0

Я немного поздно, чтобы ответить, но вот мои 2 цента, когда я сталкивался с подобной проблемой, чтобы решить проблему неспособности Autolayout для обнаружения Compact Ширина/Compact Высота для iPhone с прошивкой 7. В iOS 7 нет activated, поэтому мне пришлось добавлять/удалять их.

Я создал два метода для добавления и удаления ограничений, и эти ограничения уже установлены на IB, и я ссылаюсь на них с помощью свойств IBOutlet. Поэтому, поскольку я удаляю их, в отличие от других объектов IB, я должен установить их в strong, а не weak. В противном случае, как только я их удалю, они будут уничтожены, и я не смогу ссылаться на них еще раз, чтобы их снова добавить.

Вот мой метод ограничения удаления:

-(void)removeiOS7andiPhone4inLandscapeToOrientation:(UIInterfaceOrientation)toInterfaceOrientation{ 

    if(!UIInterfaceOrientationIsLandscape(toInterfaceOrientation)&&(NSFoundationVersionNumber<=NSFoundationVersionNumber_iOS_7_1)&&(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)){ 
     // if iPhone with iOS 7 on portrait remove Constraints here 

    } 
} 

и здесь метод ограничения сумматор:

-(void)addiOS7andiPhone4inLandscapeToOrientation:(UIInterfaceOrientation)toInterfaceOrientation{ 

    if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation)&&(NSFoundationVersionNumber<=NSFoundationVersionNumber_iOS_7_1)&&(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)){ 
     // if iPhone with iOS 7 on landscape add Constraints here 

    } 

} 

А где называть эти методы, как вы пытались, назвать их обоих viewWillAppear (нет необходимости звонить по телефону viewWillDisappear) и viewWillTransitionToSize (в моем случае это willRotateToInterfaceOrientation, так как viewWillTransitionToSize доступен только после iOS 8). Вызов их впоследствии имеет смысл, ведь только один из них будет запущен из-за проверки их портретной/альбомной ориентации с if, прежде чем вносить необходимые изменения.

и вот мое определение willRotateToInterfaceOrientation метода:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 

    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 

    // this will be run only if orientation is on Portrait 
    [self addiOS7andiPhone4inLandscapeToOrientation:toInterfaceOrientation]; 

    // this will be run only if orientation is on Landscape 
    [self removeiOS7andiPhone4inLandscapeToOrientation:toInterfaceOrientation]; 
} 

и сделать подобный вызов в viewWillAppear.

ВНИМАНИЕ: убедитесь, что вы делаете прямо противоположное в этих методах, и вы не обязательно добавлять ограничения только в addConstraintMethod и удалить только в removeConstraintMethod. В моем случае я добавляю и удаляю ограничения в каждом из них, поэтому называние методов не отражает их истинную роль в точности, но пока вы делаете точные противоположности, вам хорошо идти.

Смежные вопросы