首页 > 解决方案 > iOS 14.0 Beta 中反复调用 DispatchQueue.main.asyncAfter

问题描述

下面的延迟代码在 iOS 14.0 以下运行良好,但在 iOS 14.0 模拟器中,它每 2 秒重复调用一次。有什么我错过的吗?

  DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds.
      // Code you want to be delayed
   }

在这里,我添加了完整的代码:

    struct ContentView: View {
    
    @State var show = false
    
    var body: some View {
        NavigationView{
            
            VStack{
                NavigationLink(destination: Text("New View"), isActive: $show, label: {
                    Image("main_logo").renderingMode(.original).frame(width: 100, height: 100)
                })
                    .onAppear {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
                        self.show.toggle()
                        }
                }
            }  .navigationBarHidden(true)
                .navigationBarTitle(Text("Home"))
                .edgesIgnoringSafeArea([.top, .bottom])
            
            
            
        }.preferredColorScheme(.dark) // white tint on status bar
        
    }
}

我在两秒后从这里调用新视图,新视图在两秒后关闭并返回到上面重复的视图。

这就是我在控制台输出中得到的

[UIContextMenuInteraction] Attempting -[UIContextMenuInteraction dismissMenu], when not in an active state. This is a client error most often caused by calling dismiss more than once during a given lifecycle. (<_UIVariableGestureContextMenuInteraction: 0x60000121a920>)

我正在使用 Mac OS - Big Sur Beta 和 Xcode 12 Beta

标签: iosswiftswiftui

解决方案


.onAppear {
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    self.show.toggle()    // << this !!
    }
}

..self.show.toggle()进行body重建和NavigationLink重新创建(因为它取决于show,因此.onAppear再次调用(因为它是新链接),您会看到 - 循环往复。

所以没有错DispatchQueue.main.asyncAfter

可能您打算将该 .onAppear 修饰符附加到根视图,即。大概NavigationView

更新:以下测试在 Xcode 12 / iOS 14 上工作

struct ContentView: View {
    
    @State var show = false
    
    var body: some View {
        NavigationView{
            
            VStack{
                NavigationLink(destination: Text("New View"), isActive: $show, label: {
                    Image("main_logo").renderingMode(.original).frame(width: 100, height: 100)
                })
            }  .navigationBarHidden(true)
                .navigationBarTitle(Text("Home"))
                .edgesIgnoringSafeArea([.top, .bottom])
        }.preferredColorScheme(.dark) // white tint on status bar
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
                self.show.toggle()
            }
        }
    }
}


推荐阅读