Swift UI — галопом по Европам
22:35. Восторг
Просмотрел WWDC 2019 Key Notes. Ожидаемый декларативный UI действительно стал явью, и это воистину событие вселенского масштаба для мира iOS-разработки. «Надо написать об этом статью», — подумал я и еще тысячи iOS-разработчиков по всему миру, пребывающих в состоянии экзальтации.
05:30. Туториалы
Swift UI — новый framework, разработанный Apple, написан на Swift, предназначен для декларативного описания UI в коде.
Заметил, что с каждым годом в плане документации у «Яблока» становится все круче и круче. В этот раз под Swift UI они запилили несколько полноценных туториалов с пошаговым добавлением и интерактивным отображением результата на view, а в конце еще заботливо добавили контрольные вопросы для закрепления пройденного. Ну прям сказка! Там же — ссылки на example-проекты.
Красиво!
Не буду пересказывать туториал на русском языке, в таком прекрасном виде его лучше потыкать в первоисточнике. Опишу свои впечатления и наблюдения по поводу всей этой истории cо Swift UI и немного побалуюсь с ним.
07:00. Установка
В новом Xcode появился новый режим редактирования кода — Edit And Canvas.
Канвас я увидел не сразу — для этого мало скачать Xcode 11.0, нужно еще обновить и Макось до 10.15. Без нее Xcode работать будет, но без прелестей в виде канваса и, возможно, чего-то еще.
Порадовало, что, когда выделяешь код, выделятся и соответствующий ему элемент в канвасе.
Новая ось, exampl«ы запущены. Крашится? Ну да, бывает. Подсветка отваливается? Нет конечно — в Xcode такого же никогда не было ;) Но канвас работает, и изменения вьюшки отражаются моментально, если это не таблица со сложными ячейками.
09:22. Новый проект
При создании нового проекта теперь доступна опция Use Swift UI и проект создается с соответствующей конфигурацией.
Сразу бросается в глаза новый файл 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
указывается там же. Все встало на свои места.
Но вернемся к 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 : 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.
А еще видно, что нет автолэйаута. Нет 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-разработчиками, и круто, что эта новая дорога, пусть и не идеальная, открылась.
Ну, а пока ничего не мешает использовать это в своих пет-проектах, набивать руку и получать эстетическое наслаждение:)