В SwiftUI я создал структуру, которая должна создавать различные представления наложения в зависимости от некоторых переменных состояния. Если какое-либо из логических значений состояния истинно, оно должно возвращать настраиваемое представление (либо ErrorOverlay
, либо LoadingOverlay
, либо EmptyView
) следующим образом:
struct OverlayContainer: View {
@State var isLoading: Bool = false
@State var isErrorShown: Bool = false
func setIsLoading(isLoading: Bool) {
self.isLoading = isLoading
}
func setIsErrorShown(isErrorShown: Bool) {
self.isErrorShown = isErrorShown
}
var body: some View {
Group {
if(isErrorShown) {
ErrorOverlay()
}
else if(isLoading) {
LoadingOverlay()
}
else {
EmptyView()
}
}
}
}
Теперь я реализовал наложение для некоторого содержимого в домашнем представлении с кнопками, которые должны изменить состояние и показать правильное наложение, например:
struct Home: View {
var body: some View {
let overlayContainer = OverlayContainer()
return HStack {
// Some more content here
Button(action: {
overlayContainer.setIsLoading(isLoading: true)
}) {
Text("Start loading")
}
Button(action: {
overlayContainer.setIsErrorShown(isErrorShown: true)
}) {
Text("Show error")
}
}.overlay(overlayContainer)
}
}
Это не работает: когда я нажимаю кнопку, ничего не происходит. Почему и как это решить? (без привязки см. ниже)
пс. Мне удалось получить рабочее решение, выполнив следующие действия:
- извлечение логических значений состояния в домашнее представление
- передать их через конструктор OverlayContainer
- изменить логические значения состояния вместо вызова методов набора при нажатии кнопок
- измените OverlayContainer, чтобы он реализовал метод
init
с обоими логическими значениями - измените логические значения состояния в OverlayContainer на bindings.
Однако я хотел бы реализовать состояния в OverlayContainer, чтобы иметь возможность повторно использовать его на разных экранах, без реализации переменных состояния на всех этих экранах. Во-первых, потому что, вероятно, будет больше случаев, чем только эти 2. Во-вторых, потому что не все экраны должны будут иметь доступ ко всем состояниям, и я не нашел простого способа реализовать необязательные привязки с помощью метода init.
To Мне кажется, что все эти состояния принадлежат OverlayContainer, и изменение состояния должно быть как можно более коротким и понятным. Определение состояний повсюду похоже на дублирование кода. Может мне нужна совсем другая архитектура?