使用 NavigationLink isActive 时视图之间的动画不起作用

Animation between views not working when using NavigationLink isActive

我是从 UIKit 转到 SwiftUI 的,我遇到了 NavigationLink 在呈现新视图时没有动画的问题。

我已将视图结构设置为在以下 属性 非零时包含 NavigationLink:

@State private var retrievedDeviceIdentity: Proteus.DeviceIdentity?

Proteus.DeviceIdentity类型是一个基本的数据结构。此 属性 由成功的异步闭包填充,而不是直接的用户交互。因此,视图结构是这样设置的,使用 NavigationLink 的 destination:isActive:label: 初始化程序:

var body: some View {
    NavigationView {
        VStack {
            Form {
                // Form building
            }
            
            if let deviceIdentity = retrievedDeviceIdentity {
                NavigationLink(
                    destination: AddDeviceLinkDeviceForm(deviceIdentity: deviceIdentity),
                    isActive: .constant(retrievedDeviceIdentity != nil),
                    label: {
                        EmptyView()
                    }
                )
                .onDisappear() {
                    updateSyncButtonEnabledState()
                }
            }
        }
    }
}

retrievedDeviceIdentity 填充为非零时,确实会显示新视图。但是,没有到该视图的幻灯片过渡;它只是立即改变。在该新视图中,点击后退按钮 将幻灯片切换回该视图。

有什么解决办法吗?由于我是 SwiftUI 的新手,如果我将新结构设置错误,那么我也欢迎对此提出反馈。

(我在 macOS Big Sur 11.0.1 上使用 Xcode 12.3。)

我认为这是由于条件注入,尝试将其永久包含在视图层次结构中(因此在 NavigationView 中注册),例如

VStack {
    Form {
        // Form building
    }
}
.background(
    NavigationLink(
        destination: AddDeviceLinkDeviceForm(deviceIdentity: retrievedDeviceIdentity),
        isActive: .constant(retrievedDeviceIdentity != nil),
        label: {
            EmptyView()
        }
    )
    .onDisappear() {
        updateSyncButtonEnabledState()
    }
)

注意:我不确定你对 .onDisappear 的期望以及你为什么需要它,可能需要它移动到其他地方或在不同的修饰符下。

@Asperi 接近了,但是移动 NavigationLink 导致视图根本不显示。

所做的 工作是删除 if 大括号展开 retrievedDeviceIdentity:

var body: some View {
NavigationView {
    VStack {
        Form {
            // Form building
        }
        
        NavigationLink(
            destination: AddDeviceLinkDeviceForm(deviceIdentity: deviceIdentity),
            isActive: .constant(retrievedDeviceIdentity != nil),
            label: {
                EmptyView()
            }
        )
        .onDisappear() {
            updateSyncButtonEnabledState()
        }
    }
}

这需要将 AddDeviceLinkDeviceForm 的 deviceIdentity 属性 设为可选以接受包装值。