.sheet:只显示一次,以后再也不显示 [英] .sheet: Shows only once and then never again
问题描述
使用 Beta4 时,似乎该错误仍然存在.下面的视图序列(一个列表,点击一个列表条目会打开另一个列表)允许只显示一次 ListView
;onDisappear
永远不会被调用,因此 showModal
标志会发生变化,但再次点击时不会触发 ListView
的重新显示.因此,对于每个 GridCellBodyEntry
,.sheet
演示文稿只工作一次,以后再也不会工作了.
Working with Beta4, it seems that the bug is still existing. The following sequence of views (a list, where a tap on a list entry opens another list) allows to present the ListView
exactly once; the onDisappear
is never called, so the showModal
flag changes, but does not triggers the redisplay of ListView
when tapped again. So, for each GridCellBodyEntry
, the .sheet
presentation works exactly once, and then never again.
我尝试了一些建议和解决方法,但都没有奏效(例如,使用 NavigationViewModel 进行封装).我什至试图删除 List,因为假设 List
会导致这种行为,但即使这样也没有改变任何东西.
I tried around with several suggestions and workarounds, but none worked (e.g., encapsulating with a NavigationViewModel). I even tried to remove the List, because there was an assumption that the List
causes that behaviour, but even this did not change anything.
有什么想法吗?
设置:
- 带有此视图的
GridCellBody
:
var body: some View {
GeometryReader { geometry in
VStack {
List {
Section(footer: self.footerView) {
ForEach(self.rawEntries) { rawEntry in
GridCellBodyEntry(entityType: rawEntry)
}
}
}
.background(Color.white)
}
}
}
- 具有以下定义的
GridCellBodyEntry
:
struct GridCellBodyEntry: View {
let entityType: EntityType
let viewModel: BaseViewModel
init(entityType: EntityType) {
self.entityType = entityType
self.viewModel = BaseViewModel(entityType: self.entityType)
}
@State var showModal = false {
didSet {
print("showModal: \(showModal)")
}
}
var body: some View {
Group {
Button(action: {
self.showModal.toggle()
},
label: {
Text(entityType.localizedPlural ?? "")
.foregroundColor(Color.black)
})
.sheet(isPresented: $showModal, content: {
ListView(showModal: self.$showModal,
viewModel: self.viewModel)
})
}.onAppear{
print("Profile appeared")
}.onDisappear{
print("Profile disappeared")
}
}
}
- 具有以下定义的
ListView
:
struct ListView: View {
// MARK: - Private properties
// MARK: - Public interface
@Binding var showModal: Bool
@ObjectBinding var viewModel: BaseViewModel
// MARK: - Main view
var body: some View {
NavigationView {
VStack {
List {
Section(footer: Text("\(viewModel.list.count) entries")) {
ForEach(viewModel.list, id: \.objectID) { item in
NavigationLink(destination: ItemView(),
label: {
Text("\(item.objectID)")
})
}
}
}
}
.navigationBarItems(leading:
Button(action: {
self.showModal = false
}, label: {
Text("Close")
}))
.navigationBarTitle(Text(viewModel.entityType.localizedPlural ?? ""))
}
}
}
BaseViewModel
(摘录):
class BaseViewModel: BindableObject {
/// The binding support.
var willChange = PassthroughSubject<Void, Never>()
/// The context.
var context: NSManagedObjectContext
/// The current list of typed items.
var list: [NSManagedObject] = []
// ... other stuff ...
}
其中 willChange.send()
每当发生变化(创建、修改、删除操作)时都会调用.
where willChange.send()
is called whenever something changes (create, modify, delete operations).
推荐答案
这是 swiftUI PresentaionLink 第二次不工作
以下简化代码展示了您遇到的行为(工作表仅显示一次):
The following simplified code exhibits the behavior you're experiencing (the sheet only displays once):
import SwiftUI
struct ContentView: View {
@State var isPresented = false
@State var whichPresented = -1
var body: some View {
NavigationView {
List {
ForEach(0 ..< 10) { i in
Button(action: {
self.whichPresented = i
self.isPresented.toggle()
})
{ Text("Button \(i)") }
}.sheet(isPresented: $isPresented, content: {
Text("Destination View \(self.whichPresented)") })
}
}
}
}
当您将 .sheet
放入 List 或 ForEach 时,SwiftUI 中似乎存在错误.如果您将 .sheet
移到列表之外,您应该能够获得正确的行为.
There appears to be a bug in SwiftUI when you put the .sheet
inside a List or a ForEach. If you move the .sheet
outside of the List, you should be able to get the correct behavior.
import SwiftUI
struct ContentView: View {
@State var isPresented = false
@State var whichPresented = -1
var body: some View {
NavigationView {
List {
ForEach(0 ..< 10) { i in
Button(action: {
self.whichPresented = i
self.isPresented.toggle()
})
{ Text("Button \(i)") }
}
}
}.sheet(isPresented: $isPresented, content: { Text("Destination View \(self.whichPresented)") })
}
}
这篇关于.sheet:只显示一次,以后再也不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!