.sheet:只显示一次,然后再也不显示

Posted

技术标签:

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

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

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

有什么想法吗?

设置:

    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() 在发生变化时调用(创建、修改、删除操作)。

【问题讨论】:

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

【讨论】:

我相应地修改了我的代码,但仍然有相同的效果。然后我用你的代码替换了我的代码,它仍然只显示一次。 这也发生在滚动视图中

以上是关于.sheet:只显示一次,然后再也不显示的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的Windows server 2016 一开机就不显示桌面,只显示cmd?

Google Sheet Script:有没有办法在不停止脚本的情况下显示消息?

CircularProgressIndicator 只显示一次

函数只显示一次属性

Excel不同的Sheet间引用,公式横着拉,如何字母不变而数字变呢?

RedisDesktopManager软件窗口不显示