You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI如何为自定义按钮和NavigationLink传入不同功能与目标视图?

SwiftUI 自定义Button和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("执行注册操作")
}

用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:01:20