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

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]>
)
4b9b3361

Ответ 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 он получит этот кадр для вашего вида контроллера представления и компоновки соответствующих объектов.

Надеюсь, что это поможет.