Большинство примеров показа Alert
в presentation
относятся к некоторому виду @State
, используемому в качестве привязки, которая контролирует представленный / скрытый состояние представления оповещения.
В качестве примера showingAlert
( source ):
struct ContentView : View {
@State var showingAlert = false
var body: some View {
Button(action: {
self.showingAlert = true
}) {
Text("Show Alert")
}
.presentation($showingAlert) {
Alert(
title: Text("Important message"),
message: Text("Wear sunscreen"),
dismissButton: .default(Text("Got it!"))
)
}
}
}
Это хорошее решение, когда оповещение запускается со слоя пользовательского интерфейса - как в примере:
Button(action: {
self.showingAlert = true
}
Но что, если мы захотим запустить его из уровня контроллера / модели представления с конкретным сообщением? В качестве примера мы делаем сетевой вызов - URLSession
Publisher
может отправить Data
или Error
, которые мы хотим передать пользователю в виде сообщения в Alert
.
@State
разработан для управления из body
представления, поэтому, похоже, что в этом случае нам лучше использовать @ObjectBinding
. Кажется, нам также нужно немного message
, поэтому мы можем ссылаться на него в body
:
Alert(
title: Text("Important message"),
message: Text(objectBinding.message)
)
Здесь showingAlert
будет немного избыточным, поскольку мы можем определить message
как String?
и создать привязку для presentation
:
Binding<Bool>(
getValue: { objectBinding.message != nil },
setValue: { if !$0 { objectBinding.message = nil } }
)
Это выполнимый подход, и он работает, но меня беспокоит две вещи:
- Тот факт, что
message
управляется двумя абстракциями
- Информация и управление состоянием представленного / скрытого предупреждения, просочившегося в привязку контроллера / viewmodel / object. Было бы неплохо сохранить состояние представлено / скрыто в частном порядке в представлении.
- Тот факт, что сообщение хранится в привязке контроллера / viewmodel / object до тех пор, пока оно не будет "потреблено" видом (связыванием).
Можно ли сделать лучше?