Как стать автором
Обновить
63.11
ПСБ
ПСБ – один из десяти крупнейших банков страны

Исправление неоднозначных ограничений без перезапуска приложения

Время на прочтение4 мин
Количество просмотров2.1K
Автор оригинала: Marcos

Примечание

Слова layout, autolayout и constraints я перевёл, соответственно, как вёрстка, автовёрстка и ограничения.

Работа с автовёрсткой

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

Interface Builder неплох как визуальный редактор вёрстки. В нём есть индикация некорректных граничных параметров. Однако ваша вёрстка может отличаться от видимой в IB. На экран приложения могут влиять различные параметры — например, ответы на сетевые запросы или локально сохранённые данные. Более того, могут быть экраны, частично или полностью построенные на информации, заданной сервером. От сервера может поступать вообще всё что угодно, в том числе шрифты, цвета и формы.

Кажется, остаётся только вручную разбирать гигантский лог ошибок автовёрстки. Но есть и другие варианты. Например, сервис для начинающих WTFAutoLayout (WTF значит “Why The Failure”, т. е. «почему сломалось», а не то, о чём вы подумали), который переводит загадочные сообщения об ошибках в красивое визуальное представление проблемы.

Спасибо jpmmusic за этот сервис

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

  1. экран выглядит так же, как и во время ошибки;

  2. установленная вёрстка совпадает с той, что была во время ошибки;\

  3. ошибки автовёрстки действительно пропали.

Учитывайте, что состояние приложения могло измениться. Может быть, после перезапуска приложения ответ сервера изменился, и содержимое, которое вызывало ошибку, просто не поступило. Это может касаться, например, слишком длинных текстов в ячейках.

View Debugger + LLDB спешат на помощь

View Debugger в составе Xcode — это отличный инструмент, помогающий разобраться, из чего состоит пользовательский интерфейс и как отлаживать ошибки автовёрстки. Если вы никогда не пользовались View Debugger, я рекомендую посмотреть этот видеоролик с разбором интерфейса; в этой статье подробного руководства по View Debugger не будет.

Одна из мощных возможностей View Debugger — отображение предупреждений и ошибок вёрстки. Это сильно экономит время на поиск причин, вызывающих проблемы автовёрстки.

Вёрстка простого экрана с неоднозначными ограничениями
Вёрстка простого экрана с неоднозначными ограничениями
Список ошибок вёрстки в навигаторе ошибок
Список ошибок вёрстки в навигаторе ошибок

Теперь можно перейти к конфликтному экрану и прочитать описание ошибки на вполне человеческом языке: “Height and vertical position are ambiguous” («Высота и вертикальная позиция неоднозначны»). Перейдём к LLDB. Мы реализуем ключевую концепцию, представленную на WWDC 2018 под названием «Продвинутая отладка в Xcode и LLDB». Если вы её ещё не видели, я настоятельно рекомендую ознакомиться с ней.

Попробуем исправить ошибки вёрстки без перезапуска приложения и без перезагрузки текущего экрана. Этот подход сэкономит много времени и просто необходим, если воспроизвести ошибку вёрстки не получается.

Вот план:

  1. Запустим View Debugger

  2. Деактивируем ошибочное ограничение

  3. Применим верное ограничение

  4. Обновим вёрстку прямо из отладчика LLDB

  5. Убедимся, что все ошибки и предупреждения автовёрстки пропали

  6. ПРОФИТ

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

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let colorView = UIView()
        colorView.translatesAutoresizingMaskIntoConstraints = false
        colorView.backgroundColor = .lightGray
        view.addSubview(colorView)
        NSLayoutConstraint.activate([
            colorView.heightAnchor.constraint(greaterThanOrEqualToConstant: 277),
            colorView.widthAnchor.constraint(equalToConstant: 242),
            colorView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            colorView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
            ])
    }
}

При запущенном приложении и активном экране симулятора делаем Alt+ЛКМ на иконке View Debugger:

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

Alt+ЛКМ на кнопке, отмеченной на скриншоте выше, если симулятор находится на переднем плане, открывает View Debugger и оставляет приложение симулятора работающим. Этот трюк является важной частью нашего метода: так мы можем проверять обновления пользовательского интерфейса в реальном времени.

View Debugger открывается, а приложение остаётся в прерванном состоянии (на точке останова). Скопируйте конфликтующее ограничение (в примере view.height >= 277 @ 1000) с помощью ⌘ C и перейдите в LLDB.

Перед действиями в LLDB может понадобиться импортировать UIKit. Выполните следующую команду: expr @import UIKit.

Это копирование поместит в буфер обмена адрес ограничения с приведением типа в таком формате: ((NSLayoutConstraint *) 0x600002a01810. Теперь его можно использовать, чтобы деактивировать ограничение:

e ((NSLayoutConstraint *)0x600002a01810).active = false;

Чтобы посмотреть текущее состояние вашего макета после деактивации ограничения, запустите e [CATransaction flush] на LLDB, и вы увидите изменения, отражённые в симуляторе (это сработает, потому что симулятор остаётся активным на переднем плане).

Теперь мы можем применить ограничение, которое, предположительно, решит нашу проблему. Надо скопировать экран из View Debugger, как уже сделали с ограничением, и добавить явное ограничение к экрану:

e [(NSLayoutDimension *)[((UIView *)0x7fac3d7060b0) heightAnchor] constraintEqualToConstant: 277].active = YES;

Выполните e [CATransaction flush]; ещё раз, чтобы убедиться, что теперь вёрстка верна, и нажмите на кнопку play/pause рядом с кнопкой «активировать все точки останова»: приложение в симуляторе продолжит работу.

Инструкции, отправленные в LLDB
Инструкции, отправленные в LLDB

Чтобы убедиться, что новое ограничение не вызывает новых проблем с макетом, снова откройте View Debugger. Система ещё раз проверит, есть ли новые предупреждения Auto Layout. Как можно видеть, их нет.

Вот и всё. В несколько простых шагов вы нашли конфликтующее ограничение, протестировали исправление и убедились, что предупреждения автовёрстки исчезли; приложение даже не пришлось перезапускать.

LLDB поддерживает псевдонимы и сценарии: советую рассмотреть этот функционал, поскольку он ускоряет отладку. Начать можно здесь.

Теги:
Хабы:
Всего голосов 13: ↑12 и ↓1+11
Комментарии2

Публикации

Информация

Сайт
www.psbank.ru
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия
Представитель
Наталья Низкоус