IOS 8 top руководство по компоновке
Один из экранов моего приложения полностью сломался при обновлении до SDK iOS 8.
Проблема заключается в том, что верхняя направляющая макета смещается вместо того, чтобы быть "привязкой" для остальных видов.
Это то, что было похоже на iOS 7:
![iOS 7 Screen]()
Это то, что похоже на iOS 8 (взято из отладчика Xcode 6 View Hierarchy):
![iOS 7 Screen]()
Как вы можете видеть, вид отображается над панелью навигации.
В верхней направляющей макета есть два ограничения: один для верхнего изображения и один для белого представления под ним.
В нижнем макете ограничений нет ограничений, только ограничения высоты на представлениях.
По какой-то причине iOS 8 решает нажать верхнюю направляющую макета на {0 -255; 0 0}
после вызова [self.view layoutIfNeeded]
в первый раз.
Кроме того, границы просмотра иногда кажутся слишком большими для устройства (т.е. Отображаются точно так же, как в унифицированном раскадровке (600x600), вместо 320x480/320x568.
Что изменилось в iOS 8, которое может испортить макет?
[EDIT]
Ниже приведен полный список ограничений для представления:
(lldb) po self.view.constraints
<__NSArrayM 0x786ac520>(
<NSLayoutConstraint:0x7c377bd0 V:[_UILayoutGuide:0x7c372f60]-(0)-[UIView:0x7c373120]>,
<NSLayoutConstraint:0x7c377c00 UIView:0x7c373120.width == UIView:0x7c3730b0.width>,
<NSLayoutConstraint:0x7c377c30 UIView:0x7c3730b0.centerX == UIView:0x7c373120.centerX>,
<NSLayoutConstraint:0x7c377c60 H:|-(0)-[UIView:0x7c3716f0] (Names: '|':UIView:0x7c3730b0 )>,
<NSLayoutConstraint:0x7c377c90 UIView:0x7c3716f0.width == UIView:0x7c3730b0.width>,
<NSLayoutConstraint:0x7c372f30 V:[_UILayoutGuide:0x7c372f60]-(129)-[UIView:0x7c3716f0]>
)
Ответы
Ответ 1
Extend Edges > Under Top Bars
проверяется по умолчанию в разделе "Расширить края" Инспектора атрибутов.
Попробуйте снять флажок Under Top Bars
.
Это помогло мне много раз, когда у меня появилось странное поведение, подобное этому.
Обратите внимание, что это свойство UIViewController, поэтому вы можете установить его в коде, если хотите.
![Under Top Bars option in Interface Builder]()
Ответ 2
Вы можете либо использовать UIBarPositionTopAttached
, либо использовать рамки и рамки обзора, я также могу предложить и связать вас с документацией Apple, которая найдите время, чтобы решить проблему.
Самый лучший и самый простой способ решить эту проблему - просто встраивать свой контроллер представления в контроллер навигации, и это все. Вы можете сделать это, просто выбрав контроллер представления и перейдя в Редактоp > Вставить в > Контроллер навигации. (Если на вашей старой панели навигации есть какой-либо контент, вы можете сначала перетащить его вниз, встроить контроллер вида в навигацию контроллер, а затем переместите кнопки панели на новой панели навигации, а затем удалите старую панель навигации)
ИЛИ
Задайте для свойства панели навигации translucent
значение NO
:
self.navigationController.navigationBar.translucent = NO;
Это позволит зафиксировать представление под рамкой под панелью навигации и панель состояния.
Если вам нужно отобразить и скрыть панель навигации, используйте
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone; // iOS 7 specific
в вашем методе viewDidLoad
.
Надеюсь, что любой из них решит вашу проблему.
Ответ 3
Я использую Xcode 6.3.1, и кажется, что ошибка вернулась в эту версию (предположительно, она была исправлена в 5.1). Мне не удалось найти работу вокруг, поэтому мне пришлось еще раз поработать над Google, и вот она:
вместо обычного Ctrl + перетаскивания в IB, просто выберите View, для которого вы хотите это сделать, и перейдите в редактор → Pin → Top Space to Superview.
Здесь источник: ССЫЛКА
Это помогло мне в моем случае.
Ответ 4
Также есть проблема. Если вы работаете только с iOS8, вы можете изменить ограничения с "topLayoutGuide.bottom-myView.top" на "topLayoutGuide.top-myView.top". Но это нарушит пользовательский интерфейс для iOS7. В обеих версиях можно написать обходное решение, поддерживающее обе версии, но нет никакой возможности заставить UI работать хорошо для обеих версий при создании пользовательского интерфейса в раскадровки.
Ответ 5
Вместо использования унифицированной раскадровки (600x600) вы должны сохранить одно из разрешений устройства для своего построителя интерфейса, а затем расставить свой экран в IB.
Если размер регулятора вашего вида составляет 600x600 в раскадровке, то в viewDidLoad он получит этот кадр для вашего вида контроллера представления и компоновки соответствующих объектов.
Надеюсь, что это поможет.