Стендап Сьогодні
📢 Канал в Telegram @stendap_sogodni
🦣 @stendap_sogodni@shevtsov.me в Федиверсі

🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!

30.04.2025

SwiftUI - рефакторинг та оточення

#СтохастичнийТаймтрекер #Ping #SwiftUI

Сьогодні додав маленьку фічу до свого стохастичного таймтрекера — а саме, можливість передивитися всі пінги, які відмічені конкретним тегом. Що корисно, щоб згадати минуле. Щоправда, я досі не зробив перегляду більше за 50 пінгів, бо для того потрібне ліниве завантаження — тож не дуже далеке минуле.

Фіча звучить зовсім простою. Запит для останніх пінгів вже є. Додаєш до нього фільтр по тегу (до речі, із CTE) та виводиш списком. Але є й проблема.

Натискання на пінг відкриває форму редагування. Така можливість, звісно, потрібна й на новому списку. Ця форма не така проста річ — бо вона є модальним вікном, та на екрані ніколи не повинно бути двох форм. Тому її стан є глобальним.

Цей стан в мене поки зберігався просто в @State var formModel на структурі застосунку, та передавався глибше через @Binding. Цього разу я прикинув, через скільки шарів доведеться прокинути @Binding та вирішив, нарешті, переробити.

У SwiftUI є можливість, схожа на контексти в React - це Оточення, @Environment. Нею можна передати вглиб структури презентації якесь значення. Але — саме значення, не змінну, редагувати його не можна.

Або… можна? Спочатку я спробував передавати функцію-сетер, setFormModel. Це спрацювало! Далі пошукав більш ідіоматичне рішення та знайшов, що взагалі-то в @Environment можна передати Binding(FormModel), та тоді його можна буде призначати через formModel.wrappedValue = newFormModel.

(Binding, який лежить в основі моделі стану SwiftUI, як раз і є абстракцією над гетером та сетером, яка загортає змінне значення у незмінну обгортку.)

Код став гнучкіше та чистіше. До речі, в останньому SwiftUI цей @Environment значно спростили, так що якщо давно не бачили — подивіться.

🕜🏷️ Нагадаю, що я пишу Ping - застосунок на iOS для нетрадиційного обліку часу. Якщо цікаво, до бети можна доєднатися тут.