Swift UI — галопом по Европам

в 11:34, , рубрики: swift, swiftUI, Блог компании Tinkoff.ru, разработка мобильных приложений, разработка под iOS

Swift UI — галопом по Европам

Swift UI — галопом по Европам - 1

22:35. Восторг

Просмотрел WWDC 2019 Key Notes. Ожидаемый декларативный UI действительно стал явью, и это воистину событие вселенского масштаба для мира iOS-разработки. «Надо написать об этом статью», — подумал я и еще тысячи iOS-разработчиков по всему миру, пребывающих в состоянии экзальтации.

05:30. Туториалы

Swift UI — новый framework, разработанный Apple, написан на Swift, предназначен для декларативного описания UI в коде.

Заметил, что с каждым годом в плане документации у «Яблока» становится все круче и круче. В этот раз под Swift UI они запилили несколько полноценных туториалов с пошаговым добавлением и интерактивным отображением результата на view, а в конце еще заботливо добавили контрольные вопросы для закрепления пройденного. Ну прям сказка! Там же — ссылки на example-проекты.

Swift UI — галопом по Европам - 2
Красиво!

Не буду пересказывать туториал на русском языке, в таком прекрасном виде его лучше потыкать в первоисточнике. Опишу свои впечатления и наблюдения по поводу всей этой истории cо Swift UI и немного побалуюсь с ним.

07:00. Установка

В новом Xcode появился новый режим редактирования кода — Edit And Canvas.

Swift UI — галопом по Европам - 3

Канвас я увидел не сразу — для этого мало скачать Xcode 11.0, нужно еще обновить и Макось до 10.15. Без нее Xcode работать будет, но без прелестей в виде канваса и, возможно, чего-то еще.

Порадовало, что, когда выделяешь код, выделятся и соответствующий ему элемент в канвасе.

Новая ось, exampl’ы запущены. Крашится? Ну да, бывает. Подсветка отваливается? Нет конечно — в Xcode такого же никогда не было ;) Но канвас работает, и изменения вьюшки отражаются моментально, если это не таблица со сложными ячейками.

Swift UI — галопом по Европам - 4

09:22. Новый проект

При создании нового проекта теперь доступна опция Use Swift UI и проект создается с соответствующей конфигурацией.

Swift UI — галопом по Европам - 5

Сразу бросается в глаза новый файл SceneDelegate, в котором создается window и его root view. Но в AppDelegate’е о нем нет ни слова. Зато есть новый метод, создающий UISceneConfiguration:

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: «Default Configuration», sessionRole: connectingSceneSession.role)
    }

Ну а сама Default Configuration лежит в Info.plist и SceneDelegate указывается там же. Все встало на свои места.

Swift UI — галопом по Европам - 6

Но вернемся к SceneDelegate — запуск происходит именно в нем.

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

        // Use a UIHostingController as window root view controller
        let window = UIWindow(frame: UIScreen.main.bounds)
        window.rootViewController = UIHostingController(rootView: ContentView())
        self.window = window
        window.makeKeyAndVisible()
    }

UIHostingController — это обычный generic UIViewController, у которого может быть контент любого типа под новым протоколом View

open class UIHostingController<Content> : UIViewController where Content : View {
    ///
}

Протокол View прост до неприличия:

public protocol View : _View {
    associatedtype Body : View
    var body: Self.Body { get }
}

То есть ему надо лишь реализовать body.
Но фишка в том, что на этот протокол View написана целая тонна расширений, например для навешивания жестов, для отслеживания появления и исчезновения вьюшки с экрана, для отступов, рамок и еще много-много чего. Посмотреть всё это можно в доке View | Apple Developer Documentation. Это значит, что любая созданная вами вьюшка (под протоколом View) из коробки приобретают кучу всяких сверхспособностей!

Перейдем же к ContentView.swift.

struct ContentView : View {
    var body: some View {
        Text(«Hello World»)
    }
}

Тут просто: мы создаем вью из уже реализованных Views and Controls | Apple Developer Documentation. Могли бы сделать ее посложнее, используя различные контейнеры View Layout and Presentation | Apple Developer Documentation и вью, которые уже создали мы сами.

Верстка со Swift UI — это отдельная история, про которую будет написано еще много материалов, да и у Apple есть достойный туториал. Я не буду останавливаться на ней. Вернемся ко второй части ContentView.swift, там есть и такой код:

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

Очевидно по названию, что именно он отвечает за отображаемое в канвасе — и отобразит он previews, в нашем случае ContentView().

Попробуем же создать экран с примитивной таблицей:

struct ContentView : View {
    var birds: [Birds] = []

    var body: some View {
        List(birds) { bird in
            Text(verbatim: bird.name)
        }
    }
}

Всё. Готово. Просто, лаконично, элегантно. Вот она вся прелесть от декларативного UI!

Видно, что List — это таблица под капотом. Но не UITableView, а некая UpdateCoalesingTableView.

Swift UI — галопом по Европам - 7

А еще видно, что нет автолэйаута. Нет contstaint’s, всё на фреймах, а значит, нет этих сложных систем с линейными уравнениями и кучей расчетов. Но, с другой cтороны, верстка выходит адаптивной и фрейм как-то да рассчитывается — посмотрим в дальнейших сессиях WWDC, как именно.

Swift UI — обертка ли это над UIKit’ом? Похоже, что и да, и в то же время нет.

Joe Groff пишет следующее у себя в твиттере:

«Некоторые сущности — это обертки над UI/NS views, но тот факт, что они это делают, и то, какого типа вьюшку они оборачивают, — это вещь, которая может меняться».

Оригинал:
Some things wrap UI/NS views, but whether they do, and what view type they wrap, is subject to change. Best to think about it as a distinct thing.

Что заметил еще:

11:00. Итого

Увы, все эти прелести

@available (iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)

То есть переходить на них — это отказываться от старых осей, что слишком радикально и лишено заботы о пользователе.

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

Swift UI — прям революция в мире человеков, называющих себя iOS-разработчиками, и круто, что эта новая дорога, пусть и не идеальная, открылась.

Ну а пока ничего не мешает использовать это в своих пет-проектах, набивать руку и получать эстетическое наслаждение :)

Автор: Алексей Зверев

Источник

* - обязательные к заполнению поля