在 SwiftUI 中对导航栏项目重新使用相同的代码

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

我正在设置一个带有 TabView 导航和单独的 NavigationStack 的 SwiftUI 应用程序(以保留每个堆栈的单独导航状态)。

令我困惑的一件事是我希望在每个视图的右上角导航栏中都有相同的个人资料按钮。添加如下导航栏项目需要我在每个视图中具有完全相同的代码/添加。

.navigationDestination(isPresented: $presentProfilePage) {
    ProfileView()
}
.toolbar {
    Button {
        presentProfilePage = true
    } label: {
        if let img = user.displayImg {
            Image(uiImage: img)
                .resizable()
                .frame(width: 48, height: 48)
        } else {
            Image.defaultProfileImage
        }
    }
}

有没有办法设置导航栏项目一次,然后它们在所有视图上都可见?

swiftui navigationbar tabview swiftui-navigationstack navigationbaritems
1个回答
0
投票

您可以将此代码放在

ViewModifier
中。您可以将
presentProfilePage
作为
@State
放入其中。

struct ProfileNavigation: ViewModifier {
    @State var presentProfilePage = false
    let image: UIImage?
    
    func body(content: Content) -> some View {
        content
            .navigationDestination(isPresented: $presentProfilePage) {
                ProfileView()
            }
            .toolbar {
                Button {
                    presentProfilePage = true
                } label: {
                    if let image {
                        Image(uiImage: image)
                            .resizable()
                            .frame(width: 48, height: 48)
                    } else {
                        Image.defaultProfileImage
                    }
                }
            }
    }
}

extension View {
    func profileNavigation(image: UIImage?) -> some View {
        modifier(ProfileNavigation(image: image))
    }
}

您只需将

.profileNavigation(...)
添加到您想要拥有此按钮的每个视图即可。

或者,您可以直接在

NavigationLink
中使用
toolbar
。您只需将
NavigationLink
提取为
View
即可重复使用它:

struct ProfileNavigation: View {
    let image: UIImage?
    
    var body: some View {
        NavigationLink {
            ProfileView()
        } label: {
            if let image {
                Image(uiImage: image)
                    .resizable()
                    .frame(width: 48, height: 48)
            } else {
                Image.defaultProfileImage
            }
        }
    }
}

用途:

.toolbar {
    ProfileNavigation(...)
}
© www.soinside.com 2019 - 2024. All rights reserved.