swiftui - 从列表触发时未显示 SwiftUI 警报
问题描述
当用户点击图像视图时,我试图显示带有一些文本的警报。图像视图是用于构建单个列表项的 foreach 循环的一部分。
该按钮正在工作,它正在触发 Observable 对象的更改,但没有触发警报 isPresented ......这太令人困惑了!
该视图嵌套在几个视图中以简化代码。我分享了代码片段来说明我的问题。希望这对某人有意义,并且可以提出解决方案。
这是包含视图:
struct AssignmentsBoardView: View {
@ObservedObject var presenter: AssignmentPresenter
@ObservedObject var dogAlert: BookingNotesAlert = BookingNotesAlert()
init(_ presenter: AssignmentPresenter) {
self.presenter = presenter
}
var body: some View {
VStack {
Spacer()
if (presenter.state == ViewState.loading) {
LoadingIndicator(label: "Fetching collections")
} else if (presenter.state == ViewState.complete) {
VStack {
BoardDriversView(drivers: self.presenter.boardDrivers, currentDriver: self.presenter.selectedDriver, onSelected: self.changeDriver(boardDriver:))
AssignmentTypeHeaders(setCollections: {
self.changeAssignmentState(state: AssignmentState.collections)
}, setDropOffs: {
self.changeAssignmentState(state: AssignmentState.dropOffs)
}, currentAssignmentType: self.presenter.assignmentState)
ScrollView {
AssignmentDataView(presenter: self.presenter, dogAlert: self.dogAlert)
}
}.alert(isPresented: self.$dogAlert.showAlert, content: {
Alert(title: Text("Booking Notes"), message: Text(self.dogAlert.getDogNotes()), dismissButton: .default(Text("Ok")))
})
} else {
Text("No Assignments")
}
Spacer()
}
}
private func changeDriver(boardDriver: BoardDriver) {
self.presenter.changeSelectedDriver(driver: boardDriver)
}
private func changeAssignmentState(state: AssignmentState) {
self.presenter.changeAssignment(newState: state)
}
}
struct AssignmentDataView: View {
@ObservedObject var presenter: AssignmentPresenter
var dogAlert: BookingNotesAlert
@ViewBuilder
var body: some View {
if (self.presenter.assignmentState == AssignmentState.collections) {
if (self.presenter.collections.isEmpty) {
Text("No Collections scheduled for this driver")
} else {
ForEach(self.presenter.collections, id: \.id) { listItem in
CollectionListItem(dog: listItem, dogNotesAlert: self.dogAlert)
}
}
} else {
if (self.presenter.dropOffs.isEmpty) {
Text("No Drop Offs scheduled for this driver")
} else {
ForEach(self.presenter.dropOffs, id: \.id) { listItem in
CollectionListItem(dog: listItem, dogNotesAlert: self.dogAlert)
}
}
}
}
}
这是可观察对象:
class BookingNotesAlert: ObservableObject {
@Published var showAlert = false
var dog: DogCollectionListItem? = nil
func showAlert(dog: DogCollectionListItem) {
self.dog = dog
self.showAlert.toggle()
print("Toggled stuff")
print("Notes \(self.getDogNotes())")
}
func getDogNotes() -> String {
self.dog?.bookingNotes ?? "No notes provided"
}
}
这就是我消费它的地方:
struct CollectionListItemThumbnail: View {
var dog: DogCollectionListItem
var dogNotesAlert: BookingNotesAlert
var body: some View {
Group {
HStack {
if (!dog.bookingNotes.isEmpty) {
Button(action: {
self.dogNotesAlert.showAlert(dog: dog)
print("Tapping")
}, label: {
ImageView(withUrl: dog.thumbnailUrl, 75, highlight: true)
.padding(.trailing, 12)
.padding(.bottom, 12)
.padding(.top, 12)
})
} else {
ImageView(withUrl: dog.thumbnailUrl, 75)
.padding(.trailing, 12)
.padding(.bottom, 12)
.padding(.top, 12)
}
}
}
}
}
尝试 Asperi 的建议:
struct AssignmentsBoardView: View {
@ObservedObject var presenter: AssignmentPresenter
@State var dogAlert: BookingNotesAlert?
init(_ presenter: AssignmentPresenter) {
self.presenter = presenter
}
var body: some View {
VStack {
Spacer()
if (presenter.state == ViewState.loading) {
LoadingIndicator(label: "Fetching collections")
} else if (presenter.state == ViewState.complete) {
VStack {
BoardDriversView(drivers: self.presenter.boardDrivers, currentDriver: self.presenter.selectedDriver, onSelected: self.changeDriver(boardDriver:))
AssignmentTypeHeaders(setCollections: {
self.changeAssignmentState(state: AssignmentState.collections)
}, setDropOffs: {
self.changeAssignmentState(state: AssignmentState.dropOffs)
}, currentAssignmentType: self.presenter.assignmentState)
Button(action: {
let dog = self.presenter.collections[0]
dog.bookingNotes = "Test"
self.dogAlert = BookingNotesAlert(dog: dog)
}, label: {Text("Show booking notes")})
ScrollView {
AssignmentDataView(presenter: self.presenter, dogAlert: self.$dogAlert)
}
}.alert(item: $dogAlert) { dogAlert in
Alert(title: Text("Booking Notes"), message: Text(dogAlert.getDogNotes()), dismissButton: .default(Text("Ok")))
}
} else {
Text("No Assignments")
}
Spacer()
}
}
}
class BookingNotesAlert: Identifiable {
var dog: DogCollectionListItem? = nil
let id: UUID = UUID()
init(dog: DogCollectionListItem) {
self.dog = dog
print("Item Id >> \(id)")
print("Notes >> \(self.getDogNotes())")
}
func getDogNotes() -> String {
self.dog?.bookingNotes ?? "No notes provided"
}
}
这是按钮点击的控制台日志:
Item Id >> 6D695709-2894-4735-8DF6-81E36E1E8F4D
Notes >> Test
Item Id >> FB69ED3A-D462-4C08-8DD5-764C8A54A7B5
Notes >> Test
Item Id >> 484E0B22-F0BD-477A-8BE2-55F626F02609
Notes >> Test
Item Id >> F99E568F-C5BE-4B35-AEDF-E5A4A2700447
Notes >> Test
解决方案
推荐阅读
- r - sidebar-mini 被 R 中的 navbarPage 覆盖
- java - 我的返回语句不使用用户插入的数据
- javascript - 通过键盘按下打破 JS 中的无限循环
- c# - 检查文本是否包含字符串
- reactjs - React MUI - 选定选项卡的覆盖样式不起作用
- javascript - 如何从 React.js 向联系表格 7 发送帖子请求
- docker - docker-compose 以代码 0 退出 - 将 docker run 命令转换为 docker-compose up?
- javascript - 在 Eclipse 中,单击 Ctrl+S 后光标一直跳到控制台
- python - 如何忽略烧瓶中的双斜线?
- python - 使用 pyaudio 去噪音频播放