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

Проблемы с автоопределением с iOS8 с кодом, который отлично работает на iOS7

Я занимаюсь разработкой приложения для iPhone и iPad. Он поддерживает iOS6 и iOS7, и он использует только автоматическую компоновку.

На прошлой неделе, когда Apple объявила, что iOS8 готова к прайм-тайм, я обновил один из своих iPhone и iPad как на iOS8. Я также столкнулся с XCODE до версии 6. У меня есть второй iPhone, который я оставил в iOS7.

Я сгенерировал новые исполняемые файлы с Xcode 6, и я был огорчен, увидев, что их макеты экрана были испорчены при выполнении на моих устройствах, работающих под управлением iOS8, но все еще прекрасных на iOS7. Это верно как для физических устройств, так и для эмуляторов Xcode.

Потребовалось много рытья, но теперь я понимаю, что происходит, хотя я не знаю почему.

В частности, некоторые операции автоматического макета для меня не работают на iOS8, но они отлично работают на iOS7.

Некоторые примеры, связанные с кнопкой, которую я помещаю в базовое представление, размер которого равен размеру экрана:

(1) Если я запрошу автомасштабирование, чтобы поместить горизонтальный центр кнопки (CX), равный основному горизонтальному центру обзора, результатом является то, что горизонтальный центр кнопки расположен на левом краю левого края.

(2) Если я попрошу автомасштабирование, чтобы ширина кнопки была равна 50% ширины основного представления, она не дает никакой ширины.

Я могу обойти эти проблемы следующим образом:

(1) Я прошу автомасштабировать положение центра кнопки, равное левому краю основного левого края плюс 50% ширины экрана.

(2) Я прошу автомат сделать ширину кнопки равной 50% ширины экрана.

Я медленно пробиваю себе путь, используя обходные пути, подобные этим, обратно в автоматический макет кода, который работает для меня как на iOS7, так и на iOS8. Но мне действительно интересно, что здесь происходит.

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

Это большое приложение, и я написал много сотен строк кода автоматического макета для iOS6 и iOS7, которые отлично работают для меня.

Я уже три дня настраивал и пробовал работу с iOS8, и я не был мудрее, чем был, когда начал.

У кого-нибудь есть предложения или мысли относительно того, что может быть проблемой здесь?

4b9b3361

Ответ 1

@robmayoff имеет отличный ответ для этого: fooobar.com/questions/219543/...

По сути, в iOS8 вы больше не можете вызывать setNeedsUpdateConstraints и setNeedsLayout в представлении и ожидать, что ограничения для субвью будут обновлены.

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

Пример:

Предположим, что у вас есть ViewController с корневым представлением self.view и подвью под названием containerView. containerView имеет прикрепленный к нему NSLayoutConstraint, который вы хотите изменить (в данном случае, верхнее пространство).

В iOS7 вы можете обновить все ограничения в VC, запросив новый макет для корневого представления:

self.containerView_TopSpace.constant = 0;
[self.view setNeedsUpdateConstraints];
[self.view setNeedsLayout];

В iOS8 вам нужно запросить макеты на контейнере:

self.containerView_TopSpace.constant = 0;
[self.containerView setNeedsUpdateConstraints];
[self.containerView setNeedsLayout];

Ответ 2

Вы можете найти ответы на этот вопрос полезными: Подкатегории ячейки UICollectionView не изменяются.

В большинстве случаев работы в iOS7, но не на проблемах с автоматической компоновкой iOS 8, похоже, связаны с неправильным размером корневого представления в iOS 8, особенно когда мы устанавливаем translatesAutoresizingMaskIntoConstraints в NO. Для моих представлений мне удалось установить корневой кадр в layoutSubviews (или любой соответствующий инициализатор, который имеет правильные границы), и это решило проблему.

self.contentView.frame = CGRectInset(self.bounds, 0, 0);

Как показано в ответе выше, вы также можете сделать

self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

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

Определенно ненавижу, что так много нашего времени взято с этими раздражающими ошибками.

Ответ 3

В моем случае проблема связана с ограничениями, помеченными UIView-Encapsulated-Layout-Width и UIView-Encapsulated-Layout-Height. Когда я их удалял, все вел себя так, как будто мой взгляд был нулевого размера, и все было сосредоточено в верхнем левом углу экрана. Когда я их оставил, новые ограничения работали, как ожидалось. Я также сохранил ограничения, помеченные _UILayoutSupportConstraint.