【问题标题】:.sheet: Shows only once and then never again.sheet:只显示一次,然后再也不显示
【发布时间】:2019-07-23 19:03:38
【问题描述】:

使用 Beta4,似乎该错误仍然存​​在。下面的视图序列(一个列表,点击一个列表条目会打开另一个列表)允许只显示一次ListView; onDisappear 永远不会被调用,因此 showModal 标志会发生变化,但不会在再次点击时触发 ListView 的重新显示。因此,对于每个 GridCellBodyEntry,.sheet 演示文稿只运行一次,然后再也不会出现。

我尝试了几个建议和解决方法,但都没有奏效(例如,用 NavigationViewModel 封装)。我什至尝试删除列表,因为假设 List 会导致该行为,但即使这样也没有改变任何东西。

有什么想法吗?

设置:

  1. 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)
            }
        }
    }
  1. 具有此定义的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")
        }
    }
}
  1. 具有此定义的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 ?? ""))
        }
    }
}
  1. 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() 在发生变化时调用(创建、修改、删除操作)。

【问题讨论】:

  • 我从未遇到过这个问题。不是说它没有发生,但是....一个想法。你能试试下面的吗? (1) 一个非常简单的项目——事实上,我今天发布了一个完整的答案和一个有效的回购协议——无论如何,一个简单地显示一张表并重复关闭它的项目。 (2) 添加一个简单的List,它不会做太多,只展示主/细节和状态更新。然后并且只有在那时,添加一个模态表。同样,我并不是说这不是一个错误(如果实际上它是一个错误,你有没有向 Apple 提交过文件?)我只是想排除一些自 beta 1 以来我没有见过的东西。
  • 这是我的答案的链接,其中包含一个 beta 4 项目的链接,该项目使用模型、带有关闭按钮的工作表,并且是为 beta 4 编写的:stackoverflow.com/questions/57148220/…
  • 我接受了你的 repo 项目,它成功了。然后我将VStack 更改为List,它坏了。然后我在padding()之后移动了.sheet(即,在List括号之外,它再次工作。把所有东西放在NavigationView中,仍然工作。
  • 将List 中的内容包装到ForEach 中,仍然有效。这真的很奇怪,因为这现在类似于我当前的代码,但它不起作用。有一个主要区别:当您通过environmentObject 提交视图模型时,我将其作为参数传递。将改变这一点,看看它是否有所作为。 (其实,据我了解,这应该不会有影响……但你永远不知道……)
  • 好吧,再试了一点:在master中,我取出了GeometryReader,VStack,Section-没有变化。在细节上,我取出了NavigationView,VStack- 没有变化。之前,我更改为EnvironmentObject 以移交视图模型 - 没有变化。很奇怪……

标签: swiftui


【解决方案1】:

这是swiftUI PresentaionLink does not work second time的变体

以下简化代码展示了您遇到的行为(工作表仅显示一次):

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 移到列表之外,您应该能够获得正确的行为。

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)") })
    }
}

【讨论】:

  • 我相应地修改了我的代码,但仍然有相同的效果。然后我用你的代码替换了我的代码,它仍然只显示一次。
  • 这也发生在滚动视图中
猜你喜欢
  • 2020-03-10
  • 1970-01-01
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
相关资源
最近更新 更多