Простота SwiftUI
Я буду честен. Я не хотел любить SwiftUI… но я люблю. С момента запуска SwiftUI в конце 2019 года я был непреклонен в том, что не собираюсь его использовать, и буду придерживаться исключительно UIKit.
В то время как для некоторых вещей по-прежнему требуется использовать UIKit, SwiftUI имеет этот волшебный способ упростить создание элементов пользовательского интерфейса, которые могут стать головной болью в UIKit.
Swift как язык дал команде Apple время подумать о том, что часто делают разработчики iOS, и о проблемах, с которыми столкнулся UIKit.
Вы хотите сделать что-то простое, например добавить отступ к метке или изображение внутри пользовательской кнопки с текстом? Конечно…!
Вы можете создать подкласс UILabel
и initialize
с помощью какого-либо UIEdgeInsets или добавить функции или свойства переопределения для своего подкласса, такие как intrinsicContentSize: CGSize
.
Есть много правильных решений, но SwiftUI производит сильное впечатление на ViewModifiers
.
Поиграв немного со SwiftUI за последние несколько дней, я действительно увидел привлекательность этой новой разработки Swift.
Несколько недель назад я написал статью с решением моей небольшой проблемы «Изображение в UITextField
» и решил попробовать ее в SwiftUI!
Я уверен, что многие из вас, читающих это, сочтут это тривиальным в SwiftUI.
Эта статья не предназначена для людей, которые в настоящее время изучают/знают SwiftUI. Вместо этого я хочу показать пример чего-то, что я ранее создал в UIKit, для тех, кто ищет несколько прямого сравнения.
Первый результат
Код ниже — это то, что используется для приведенного выше GIF. Это очень простой пример.
Я завернул его в NavigationView
(UINavigationController
только для пользователей UIKit) и добавил его в Form
, который кажется эквивалентным UITableView
.
Хотя это выглядит немного повторяющимся, верно? Я почти не могу поверить, что пишу это. Мы уже сэкономили на многих строках кода, настраивая наши UITableView
, UINavigationController
/UICollectionView
, NSLayoutConstraint
, UITableViewDelegate
, UITableViewDataSource
… не забывая о пользовательском UITextField
сверху!
Небольшой рефакторинг
Если мы нажмем клавишу cmd
и щелкнем HStack
, мы сможем выделить этот раздел кода в отдельное подпредставление:
Затем Swift любезно назовет это ExtractedView()
для нас, пока мы не найдем для него подходящее имя и не поместим его ниже ContentView()
.
Я собираюсь переименовать этот PersonalInfoStack
и добавить 3 новых свойства для наших image
и textField
.
Это возвращает «какой-то View
», в этом примере он вернет HStack с image
и textField
. Затем мы передаем свойства через новый конструктор, когда вызываем экземпляр PersonalInfoStack()
:
Поскольку мы используем свойство @State
в нашем новом подпредставлении, нам нужно использовать ключевое слово @Binding
здесь в нашем свойстве textFieldText: String
, чтобы сообщить Swift: «Эй, я собираюсь использовать здесь значение, но я хочу, чтобы оно было то же, что и то, что я передаю… Если я обновлю здесь, обновите его там, где он изначально объявлен».
Теперь о новом рефакторинге ContentView
:
Хорошо, добираемся.
Сейчас это выглядит маленьким. На самом деле до смешного мало для того, что у нас есть в нашем пользовательском интерфейсе. Мы не хотим перебарщивать, но давайте представим, что у вас здесь больше просмотров и много логики.
Чего мы не хотим добиться, так это проблемы MVC, когда код становится нечитаемым/сложным в управлении!
Вы можете рефакторить Section
, но будьте осторожны; есть тонкая грань между абстракцией ради здравого смысла и абстракцией, которая настолько абстрактна, что вы не можете понять, что происходит!
Лично мне нравится оставлять определенные части кода такими, какие они есть, чтобы улучшить читабельность, например, принять решение не рефакторить Section
.
При написании кода я часто использую alt
+ cmd
+<
или alt
+ cmd
+ >
, чтобы свернуть и открыть код. Это определенно долгожданный маленький помощник для более длинных ContentView()
:
Идем дальше!
Последним примером будет TextField
, который показывает и скрывает текст, соответствующий моей предыдущей статье. Примером этого может быть какой-то пароль или безопасный вход.
В UIKit мы бы установили для свойства textField.isSecureTextEntry
значение = true
. В SwiftUI мы можем написать следующее:
Как вы можете видеть выше, мы добавили логическое значение, которое определяет, виден пароль или нет.
Это логическое значение также определяет, какой тип изображения используется для изображения с помощью тернарного оператора:
Это не дамп UIKit!
На самом деле я столкнулся с интересной заминкой при попытке изменить цвет фона Form
в SwiftUI и довольно быстро обнаружил, что мне пришлось вернуться к UIKit. Я ожидал, что смогу добавить модификатор Color
к Form
.
После того, как это не сработало, я попытался завернуть его в ZStack
, что тоже не сработало. Некоторое исследование позже я обнаружил следующее решение для тех, кто может найти его полезным:
Здесь это не лучший выбор цвета, но это пример необходимости переключать фреймворк и реализовывать UIKit, когда это необходимо.
Мое использование UIKit по-прежнему будет присутствовать, но только из этого небольшого примера и моего сравнения реализации одних и тех же вещей в UIKit и SwiftUI можно с уверенностью сказать, что SwiftUI будет чем-то, о чем я очень хочу узнать больше!
Спасибо за прочтение.