SwiftUI如何为自定义按钮和NavigationLink传入不同功能与目标视图?
一、自定义可传入点击事件的Button
你之前用CGFunction是错误方向,SwiftUI里传递点击逻辑应该用无参无返回的闭包,类型为() -> Void。直接把闭包作为自定义视图的属性传入即可:
修改后的自定义Button代码:
struct CommonButton: View { let buttonText: String let action: () -> Void // 定义闭包属性,接收点击逻辑 var body: some View { Button(action: action, label: { Text(buttonText) .font(.system(size:30)) // 这里可以添加你的自定义样式,比如颜色、边框、圆角等 .foregroundColor(.white) .padding(.horizontal, 40) .padding(.vertical, 12) .background(Color.orange) .cornerRadius(10) }) } }
使用示例:
// 直接传入已定义的函数 CommonButton(buttonText: "登录", action: login) CommonButton(buttonText: "注册", action: register) // 也可以直接写闭包逻辑 CommonButton(buttonText: "退出") { // 这里写退出的具体逻辑 } // 假设你已定义以下函数 func login() { print("执行登录操作") } func register() { print("执行注册操作") }
二、自定义可指定目标视图的NavigationLink
用String传递目标视图完全行不通,正确做法是使用泛型,让自定义导航链接支持任意遵循View协议的视图类型:
修改后的自定义NavigationLink代码:
// 泛型Destination约束为View类型,适配所有视图 struct CommonNavigationLink<Destination: View>: View { let destination: Destination let linkText: String var body: some View { NavigationLink(destination: destination, label: { Text(linkText) .font(.system(size:30)) // 自定义样式示例 .foregroundColor(.blue) .underline() .padding(.vertical, 8) }) } }
使用示例:
// 直接传入具体的目标视图实例 CommonNavigationLink(destination: LoginView(), linkText: "前往登录") CommonNavigationLink(destination: LandingView(), linkText: "返回首页")
额外优化:更灵活的样式复用方式
如果只是想复用样式逻辑,不想每次都封装自定义视图,还可以用ViewModifier来抽离样式:
按钮样式Modifier
struct CommonButtonStyle: ViewModifier { func body(content: Content) -> some View { content .font(.system(size:30)) .foregroundColor(.white) .padding(.horizontal, 40) .padding(.vertical, 12) .background(Color.orange) .cornerRadius(10) } } // 扩展View方便调用 extension View { func applyCommonButtonStyle() -> some View { self.modifier(CommonButtonStyle()) } } // 使用时直接给系统Button加样式 Button("登录", action: login) .applyCommonButtonStyle()
导航链接样式Modifier
struct CommonNavigationLinkStyle: ViewModifier { func body(content: Content) -> some View { content .font(.system(size:30)) .foregroundColor(.blue) .underline() .padding(.vertical, 8) } } extension View { func applyCommonNavigationLinkStyle() -> some View { self.modifier(CommonNavigationLinkStyle()) } } // 使用 NavigationLink("前往登录", destination: LoginView()) .applyCommonNavigationLinkStyle()
内容的提问来源于stack exchange,提问作者MatDuck1
相关产品推荐
相关产品推荐

