【问题标题】:Animation between views not working when using NavigationLink isActive使用 NavigationLink isActive 时视图之间的动画不起作用
【发布时间】:2020-12-23 08:52:33
【问题描述】:

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

当以下属性不为 nil 时,我已设置视图结构以包含 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。)

【问题讨论】:

    标签: animation swiftui swiftui-navigationlink


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢!我有条件地添加它,因为 retrievedDeviceIdentity 需要被解包以传递到 AddDeviceLinkDeviceForm 初始化程序中。根据您的逻辑,在该初始化程序中强制解开 retrievedDeviceIdentity 是否安全?
    • 我会将其更改为可选并在 AddDeviceLinkDeviceForm 内处理
    • 我已经尝试更新我的代码以匹配您的代码,但现在根本没有显示新视图。我确实发现将代码放在我拥有的地方,但删除 if let deviceIdentity = retrievedDeviceIdentity 展开使动画正常工作。
    【解决方案2】:

    @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 属性设为可选以接受包装的值。

    【讨论】:

      猜你喜欢
      • 2021-12-15
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 2020-06-14
      • 2016-10-16
      • 2023-01-20
      • 2020-11-21
      • 1970-01-01
      相关资源
      最近更新 更多