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

时间:2021-01-18 04:00:53

标签: ios swiftui mac-catalyst

问题

这仅在为 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)")
            }
        }
    }
}

0 个答案:

没有答案