从嵌套在父列表中的导航链接推送后列表冻结仅限 MacCatalyst

问题描述

问题

这仅在为 MacCatalyst 构建目标时发生。它在 iPhone(真实设备和模拟器)上运行良好。

我在 NavigationView 中创建了一个父列表,称之为“查询视图”。

QueryView 中的每一项都是一个 NavigationLink。这些 NavigationLink 的目标视图之一是包含另一个列表(模型视图)的视图。当导航到 ModelView 时,它的事件列表通常会在初始滚动一两次后冻结。冻结后,解冻它的唯一方法是从视图中弹出并推回,调整窗口大小,或者有时从列表中添加/删除某些内容

最小可重复示例

以下步骤适用于最小的可重现示例:

  1. 使用 UIKit LifeCycle 和 SwiftUI 界面的新 Xcode 项目
  2. 勾选 MacCatalyst 选项
  3. 添加场景委托代码
  4. 将所有其他代码添加一个文件

注意事项

• 有时它的滚动效果很好,但最终总是冻结。

• 冻结后 cpu 为 0%,但在冻结时尝试滚动时变为典型的 %15%。

• 列表是唯一冻结的 UI 部分,其他一切正常。

场景委托代码

func scene(_ scene: UIScene,willConnectTo session: UIScenesession,options connectionoptions: UIScene.Connectionoptions) {
        let rootVM = RootView.viewmodel()

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: RootView(vm: rootVM))
            self.window = window
            window.makeKeyAndVisible()
        }
    }

所有其他代码


import SwiftUI

struct RootView: View {
    
    @Observedobject var vm:viewmodel
    
    var body: some View {
        NavigationView {
            List {
                ForEach(vm.roles,id: \.rawValue) { role in
                    NavigationLink(
                        role.rawValue,destination: viewForRole(role: role)
                    )
                }
            }
        }
        .navigationBarTitle("Roles")
    }
    
    @viewbuilder func viewForRole(role: viewmodel.Role) -> some View {
        if role == .admin {
            QueryView(vm: vm.queryVM)
        }else if role == .moderator {
            Text("Coming soon!")
        }else{
            Text(role.rawValue)
        }
    }
}

extension RootView {
    
    class viewmodel:ObservableObject {
        
        let queryVM = QueryView.viewmodel()
        
        @Published var roles:[Role]
        
        enum Role:String,CaseIterable {
            case admin = "Admin"
            case moderator = "Moderator"
        }
        
        init() {
            self.roles = Role.allCases
        }
    }
}



struct QueryView:View {
    
    @Observedobject var vm:viewmodel
    
    var body: some View {
        vstack(alignment: .center) {
            TextField("Search",text: $vm.searchValue)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .frame(maxWidth: 250)
                .padding()
            List {
                ForEach(vm.models,id: \.self) { model in
                    NavigationLink(model,destination: ModelView(vm: ModelView.viewmodel()))
                }
            }
            Button("Add Model") {
                vm.addModel()
            }
            .padding()
        }
        .navigationBarTitle("Query View")
    }
    
}

extension QueryView {
    
    class viewmodel:ObservableObject {
        
        @Published var models:[String]
        
        @Published var searchValue:String
        
        init() {
            self.searchValue = "Just for looks..."
            self.models = [String]()
            for i in 0..<20 {
                models.append("Model \(i+1)")
            }
        }
        
        
        func addModel() {
            self.models.append("Model \(models.count + 1)")
        }
    }
}

struct ModelView:View {
    
    @Observedobject var vm:viewmodel
    
    var body: some View {
        HStack {
            List {
                ForEach(vm.events,id: \.self) { event in
                    Text(event)
                }
            }
            .frame(maxWidth: 300)
            Text("Other Model Form")
                .frame(maxWidth: .infinity)
        }
        .navigationBarTitle("Model View")
    }
}


extension ModelView {
    
    class viewmodel:ObservableObject {
        
        var events:[String]
        
        init() {
            self.events = [String]()
            for i in 0..<30 {
                events.append("Event \(i+1)")
            }
        }
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)