Это мой первый пост, так что терпите меня. Также оставьте любые отзывы, которые у вас есть!

UINavigationController - довольно фундаментальный строительный блок для любого приложения iOS. Как вы уже догадались, он управляет ядром навигации по представлениям в большинстве приложений. Как пользователь переходит из представления A в представление B, обычно выполняется через UINavigationController.

По сути, в приложении для iOS вы будете часто использовать UINavigationController. Тем не менее, с ним легко столкнуться с некоторыми довольно неприятными проблемами (какие в целом фреймворки Apple прекрасны, у некоторых из них есть недостатки).

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

Навигация и завершение

Представлять UIViewController как модальное окно действительно приятно.

let presentedVC = UIViewController()
self.present(presentedVC, animated: true) {
    // Handle presentation completion here
}

Посмотри на это! Вы можете сказать, анимирован он или нет, и вы получите изящный небольшой блок завершения для постобработки!

Посмотрим, что нам дает UINavigationController.

// Push a UIViewController
let pushedVC = UIViewController()
self.navigationController?.pushViewController(pushedVC, animated: true)
// Pop a UIViewController
let _ = self.navigationController?.popViewController(animated: true)

Хм. Это не кажется таким уж приятным. Что, если я захочу что-нибудь сделать, когда толкание или хлопанье закончится ?!

Продолжить чтение :)

Я обнаружил, что использование расширений довольно удобно в таких случаях, когда вам нужны некоторые функции, которых в действительности не существует. Вы можете использовать API UINavigationController, чтобы помочь с этим. Для толкания:

А для выскакивания:

Довольно просто, верно! Все, что мы здесь делаем, - это пользуемся преимуществом свойства transitionCoordinator UINavigationController для выполнения любой дополнительной работы во время анимации и ожидания завершения. Теперь, когда вы хотите узнать, когда навигация завершена, это очень просто:

// Push View Controller
let pushedVC = UIViewController()
navigationController?.pushViewController(pushedVC, animated: true) {
    // Handle completion block here
}
// // Pop View Controller
let _ = navigationController?.popViewController(animated: true) {
    // Handle completion block here
}

Настройка кнопки возврата

Одна из приятных вещей, встроенных в UINavigationController, - это возможность вернуться назад в приятной, плавной анимированной манере. Для этого есть даже встроенная кнопка возврата.

И поскольку у iOS лучший пользовательский интерфейс в мире, зачем вам его настраивать? По крайней мере, это похоже на то, что имела в виду команда Apple.

Настройка кнопки возврата для UIViewController может быть на удивление раздражающей, но это довольно просто. Если вы подклассифицируете свой контроллер навигации, вы можете просто переопределить func pushViewController(_ viewController: UIViewController, animated: animated):

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

К счастью, с помощью UINavigationController transitionCoordinator нам не нужен подкласс. Вместо этого мы можем просто реализовать метод в расширении UINavigationController, как мы это делали выше.

Довольно аккуратно! Мне лично нравится создавать подобные расширения, и когда во всем приложении есть кнопка возврата по умолчанию, это всего лишь несколько строк, которые нужно реализовать.

Тень панели навигации

Тень UINavigationBar - отличное дополнение к UINavigationBar. Это помогает красиво создать различие между видом и панелью. Его также можно настроить, что является настоящим удовольствием.

Чтобы изменить цвет тени, все, что вам нужно сделать, это установить shadowImage в UINavigationBar на изображение, полностью состоящее из одного цвета. Все просто, правда?

На самом деле это так. Единственная реальная дополнительная работа, которую вам нужно сделать, - это создать изображение из UIColor. Это можно легко добавить в расширение UIColor:

var image: UIImage? {
    get {
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContext(rect.size)
        context.setFillColor(cgColor)
        context.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

И теперь все, что вам нужно сделать, это определить метод, который принимает цвет и применяет его к navigationBar контроллера навигации:

func setShadowColor(_ color: UIColor) {
  navigationBar.setBackgroundImage(#backgroundImage, for: .default)
  self.navigationBar.shadowImage = color.image
}

Для изменения цвета теневого изображения требуется установка фонового изображения, как указано в документации Apple:

For a custom shadow image to be shown, a custom background image must also be set with the setBackgroundImage(_:for:) method. If the default background image is used, then the default shadow image will be used regardless of the value of this property.

Это лишь некоторые из вещей, которые я нашел полезными за годы работы с UINavigationController, но есть гораздо больше. Не стесняйтесь оставлять комментарии ниже!