点击导航链接时应用程序冻结

问题描述 投票:0回答:1

当我点击 NavgationLink 移至下一个屏幕时,我的视图冻结并且 CPU 使用率变为 99%

我最近更新了我的 Xcode(版本 15.0),并开始开发一个新项目。现在的问题是我在单个视图中有 4-5 NavigationLinks,当我尝试移动到下一个视图时,我的应用程序冻结在那里,我必须重新启动应用程序才能使其再次正常运行,但在相应的视图中遇到相同的问题屏幕。

这是我的代码:

struct SettingsView: View {

    var body: some View {

     VStack {
        Group {
                    
           NavigationLink {
                EditProfileView()
                    .hideNavigationBar
           } label: {
                SettingsRow(row: .editProfile)
           }
                    
           Divider()
                    
           NavigationLink {
                AccountVerificationView()
                    .hideNavigationBar
           } label: {
                SettingsRow(row: .accountVerification)
           }
                    
           Divider()
                    
           NavigationLink {
                ChangePhoneNoView()
                    .hideNavigationBar
           } label: {
                SettingsRow(row: .changeNumber)
           }
                    
           Divider()
        }
                 
     Group {
           SettingsRow(row: .notification, isToggleOn: $notificationOn)
                    
           Divider()
                    
           SettingsRow(row: .conversation, isToggleOn: $openToConversation)
                    
           Divider()
                    
           NavigationLink {
                MatchedFriends()
                   .hideNavigationBar
           } label: {
                SettingsRow(row: .matchedFriends)
         }
       }
     }
   }
}

这是我的主要观点:

@main
struct KoyApp: App {
    
    // register app delegate for Firebase setup
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
    var body: some Scene {
        
        WindowGroup {
            NavigationStack {
                SettingsView()
                    .onOpenURL(perform: { url in
                        Auth.auth().canHandle(url)
                    })
            }
        }
    }
}
struct HideNavBar : ViewModifier {
    
    func body(content: Content) -> some View {
        content
            .navigationBarTitle("")
            .navigationBarHidden(true)
            .navigationBarBackButtonHidden(true)
    }
}

extension View {
 
   var hideNavigationBar: some View {
        modifier(HideNavBar())
    }
}

这是 Xcode 中的新错误还是我做错了什么?

swift swiftui navigation swiftui-navigationlink
1个回答
0
投票

我遇到了这个问题,问题最终与访问传递到

.navigationDestination
块之外的属性有关。

这是一个存在问题的简单示例。请注意,

string
正在被访问,但并未传递到
.navigationDestination
块中:

struct MainView: View {
    @State var path = NavigationPath()
    @State var string: String = ""
    
    enum Destination {
        case detail
    }
    
    var body: some View {
        NavigationStack(path: $path) {
            Button(action: {
                path.append(Destination.detail)
            }, label: {
                Text("Push Detail view")
            })
            .navigationDestination(for: Destination.self, destination: { _ in
                DetailView(viewModel: DetailViewModel(string: string))
            })
        }
    }
}

class DetailViewModel: ObservableObject {
    var string: String
    init(string: String) {
        self.string = string
    }
}

struct DetailView: View {
    @StateObject var viewModel: DetailViewModel
    
    init(viewModel: DetailViewModel) {
        self._viewModel = StateObject(wrappedValue: viewModel)
    }
    
    var body: some View {
        Text(viewModel.string)
    }
}

一个好的经验法则似乎是仅访问传递到

.navigationDestination
块的数据。在这个简单的示例中,您可以通过将
string
值与
Destination
枚举案例关联来实现这一点。这是更新后的
MainView
结构:

struct MainView: View {
    @State var path = NavigationPath()
    @State var string: String = ""
    
    enum Destination: Hashable {
        case detail(string: String)
    }
    
    var body: some View {
        NavigationStack(path: $path) {
            Button(action: {
                path.append(Destination.detail(string: string))
            }, label: {
                Text("Push Detail view")
            })
            .navigationDestination(for: Destination.self, destination: { destination in
                if case let .detail(passedInString) = destination {
                    DetailView(viewModel: DetailViewModel(string: passedInString))
                }
            })
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.