繁体   English   中英

iOS 14.5 NavigationLink 在 withAnimation 中清除环境对象

[英]iOS 14.5 NavigationLink nils EnvironmentObjects when in the middle of withAnimation

目前在我的项目中,我有一个导航堆栈,在父级 NavigationView 中,有一个 Timer 启动一个 withAnimation 块,该块为导航堆栈中的按钮共享的属性设置动画。

在更新到 iOS 14.5 之后,当 NavigationLink 在 withAnimation 块(在这种情况下总是如此)的中间被点击时,向下传递导航堆栈的 EnvironmentObjects 变为 nil。

抛出的错误:致命错误:找不到 BackgroundViewModel 类型的 ObservableObject。 作为该视图的祖先,BackgroundViewModel 的 View.environmentObject(_:) 可能会丢失。

绝对认为它是 NavigationView 处理动画的新方式和 NavigationLinks 处理 state 方式的组合。 根据 iOS 14.5 开发人员发布说明: NavigationView push and pop now correctly respects disabled animations. (70062477) NavigationView push and pop now correctly respects disabled animations. (70062477) & The destination of NavigationLink that only differs by local state now resets that state when switching between links as expected. (72117345) The destination of NavigationLink that only differs by local state now resets that state when switching between links as expected. (72117345)

下面是一个将重新创建错误的示例。 任何帮助将不胜感激。

import SwiftUI
import Combine

struct ContentView: View {
    @StateObject var backgroundVM = BackgroundViewModel()
    @State var presentNext: Bool = false
    
    var body: some View {
        NavigationView {
            VStack{
                Text("Hello, world!")
                    .padding()
                NavigationLink(
                    destination: View2(),
                    isActive: $presentNext) {
                    Button {
                        presentNext = true
                    } label: {
                        Text("Navigate")
                    }
                }
            }
            .frame(width: 250, height: 250, alignment: .center)
            .background(backgroundVM.backgroundColor)
        }
        .environmentObject(backgroundVM)
        .onReceive(backgroundVM.timer) { _ in
            withAnimation(.easeInOut(duration: 2.0)) {
                backgroundVM.setColor()
            }
        }
    }
}

struct View2: View {
    @EnvironmentObject var backgroundVM: BackgroundViewModel
   
    @State var presentNext: Bool = false
    
    var body: some View {
        VStack {
            Text("View 2")
            NavigationLink(
                destination: View3(),
                isActive: $presentNext) {
                Button {
                    presentNext = true
                    
                } label: {
                    Text("Navigate")
                }
            }
        }
        .frame(width: 250, height: 250, alignment: .center)
        .background(backgroundVM.backgroundColor)
    }
}

struct View3: View {
    @EnvironmentObject var backgroundVM: BackgroundViewModel
    
    var body: some View {
        VStack {
            Text("View 3")
        }
        .frame(width: 250, height: 250, alignment: .center)
        .background(backgroundVM.backgroundColor)
 
    }
}

class BackgroundViewModel: ObservableObject {
    @Published var backgroundColor: Color = .orange
    @Published var colorIndex: Int = 0 {
        willSet {
            backgroundColor = colors[newValue]
        }
    }
    
    var timer = Timer.publish(every: 1.5, on: .main, in: .common)
        .autoconnect()
    
    var colors: [Color] = [.orange, .green, .purple]
    
    func setColor() {
        if colorIndex + 1 == colors.count {
            colorIndex = 0
        } else {
            colorIndex += 1
        }
    }
}

尝试

View2().environmentObject(backgroundVM)

 View3().environmentObject(backgroundVM)

你必须使用这个

 .environmentObject(backgroundVM)

每次实例化一个具有

 @EnvironmentObject

我有同样的问题。 您可以同时从以下答案中使用 singleton 查看此解决方案:

SwiftUI 中的 EnvironmentObject 与 Singleton?

这也发生在 iOS 14.6(刚刚发布)上,以及 SwiftUI 上的导航错误。 所以要小心:

iOS 14.5 的 SwiftUI NavigationLink 不工作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM