Стендап Сьогодні
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
30.04.2025
SwiftUI - рефакторинг та оточення
Сьогодні додав маленьку фічу до свого стохастичного таймтрекера — а саме, можливість передивитися всі пінги, які відмічені конкретним тегом. Що корисно, щоб згадати минуле. Щоправда, я досі не зробив перегляду більше за 50 пінгів, бо для того потрібне ліниве завантаження — тож не дуже далеке минуле.
Фіча звучить зовсім простою. Запит для останніх пінгів вже є. Додаєш до нього фільтр по тегу (до речі, із CTE) та виводиш списком. Але є й проблема.
Натискання на пінг відкриває форму редагування. Така можливість, звісно, потрібна й на новому списку. Ця форма не така проста річ — бо вона є модальним вікном, та на екрані ніколи не повинно бути двох форм. Тому її стан є глобальним.
Цей стан в мене поки зберігався просто в @State var formModel
на структурі застосунку, та передавався глибше через @Binding
. Цього разу я прикинув, через скільки шарів доведеться прокинути @Binding
та вирішив, нарешті, переробити.
У SwiftUI є можливість, схожа на контексти в React - це Оточення, @Environment
. Нею можна передати вглиб структури презентації якесь значення. Але — саме значення, не змінну, редагувати його не можна.
Або… можна? Спочатку я спробував передавати функцію-сетер, setFormModel
. Це спрацювало! Далі пошукав більш ідіоматичне рішення та знайшов, що взагалі-то в @Environment
можна передати Binding(FormModel)
, та тоді його можна буде призначати через formModel.wrappedValue = newFormModel
.
(Binding
, який лежить в основі моделі стану SwiftUI, як раз і є абстракцією над гетером та сетером, яка загортає змінне значення у незмінну обгортку.)
Код став гнучкіше та чистіше. До речі, в останньому SwiftUI цей @Environment
значно спростили, так що якщо давно не бачили — подивіться.
🕜🏷️ Нагадаю, що я пишу Ping - застосунок на iOS для нетрадиційного обліку часу. Якщо цікаво, до бети можна доєднатися тут.