SwiftUI [演示] / 尝试在已经展示的视图控制器上呈现另一个视图控制器

17

我正在开发一款SwiftUI应用程序,但是首先遇到了警告,然后出现了错误,可能是因为我忽略了这些警告。我希望展示我收到的警告,并希望有人能指出我可能做错的事情。

以下是相关代码:

struct CustomListView: View {
    var localList:[SomeManagedObject], moc:NSManagedObjectContext
    @State var showingOtherView = false
    
    func handleCustomItem(_ argument: SomeManagedObject) {
        print(#function)
        self.showingOtherView.toggle()
        ..... Do useful things .....
    }
    
    var body: some View {
        List {
            ForEach(self.localList) {
                item in
                HStack {
                    Spacer()
                    Button(action: {
                        self.handleCustomItem(item)
                    })
                    {
                        Text(item.expression!)
                            .foregroundColor(Color.red))
                            .font(.headline)
                            .padding(.horizontal, 11).padding(.vertical, 15)
                    }.sheet(isPresented: $showingOtherView) {
                        OtherView()
                    }
                    Spacer()
                }
            }
        }
    }
}

这是OtherView的代码:

import SwiftUI
import CoreData

struct OtherView: View {

    var body: some View {
        Text("Hello OtherView")
    }
}

以下是我点击列表中的一个按钮并执行handleCustomItem()函数时在调试控制台中看到的消息:

handleCustomItem(_:) 2021-04-20 22:53:10.667895+0900 TheApp[9600:5758072] [Presentation] 尝试呈现<TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView: 0x10529a510>,但它已经在 <TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView: 0x105299150>上显示。尝试呈现<TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView: 0x10529b1b0>,但它已经在 <TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView: 0x105299150>上显示。........... 尝试呈现<TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView: 0x105118e10>,但它已经在 <TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView: 0x105299150>上显示。

如果有人能查看这些信息并给我一些提示,那将非常好。
3个回答

20

您的.sheet(isPresented: $showingOtherView) {位于ForEach中。当您将showingOtherView设置为true时,ForEach中的所有表单都会尝试呈现。那是很多表格。

您希望将其放在ForEach之外。

var body: some View {
    List {
        ForEach(self.localList) {
            item in
            HStack {
                Spacer()
                Button(action: {
                    self.handleCustomItem(item)
                })
                {
                    Text(item.expression!)
                        .foregroundColor(Color.red))
                    .font(.headline)
                    .padding(.horizontal, 11).padding(.vertical, 15)
                }
                Spacer()
            }
        }
    }
    .sheet(isPresented: $showingOtherView) { /// here should be fine
        OtherView()
    }
}

1
当我第一次尝试以你提到的方式思考时,我发现消息数量并不总是与列表中的行数匹配,因此我得出了这是错误的方法的结论。但是尝试你建议的方法确实有效,所以你一定是正确的。而且我肯定漏掉了一些细节。 - Michel
SwiftUI列表会惰性加载,因此消息数量应该接近于当前屏幕上的行数减1(第一个表格不会出现问题,但之后的每个表格都会出现错误消息)。 - aheze
1
这正是我所期望的,但似乎并非总是如此。或者每个可见单元格都有一条消息,但我还没有检查过。无论如何,错误消息现在已经消失了,这很好。但现在我又遇到了另一个问题,我无法将单元格中的信息传递给OtherView。实际上,我已经为此创建了另一个帖子:https://stackoverflow.com/questions/67189413/handling-a-list-of-buttons-in-swiftui - Michel

9

我也遇到了相同的警告消息/错误,但原因并不像你的情况那样是表数量太多。我的问题是我尝试过快地呈现一个表格然后立刻呈现另一个表格,就像这样:

naviViewModel.isSUModalPresented = false
naviViewModel.isPaidContentIntroPresented = true

我不得不改为:

naviViewModel.isSUModalPresented = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // or even shorter
     naviViewModel.isPaidContentIntroPresented = true
}

现在它可以完美地运行了。SwiftUI 只需要几毫秒就能完成动画。


1
运行得非常出色,谢谢! - John Gorenfeld

0
把你的代码放在一个 NavigationStack 中。就像这样:
var body: some View {
    NavigationStack {
        List {
            
        }
    }
}

1
你的回答可以通过提供更多的支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接