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

Swift中复用NavigationLink组件:如何减少代码重复?

解决方案:封装自定义NavigationLink组件

当然可以实现!其实和复用Button的思路完全一致,咱们只需要把重复的NavigationLink逻辑封装成一个自定义View,通过传入不同的参数(比如室友数量)来生成不同的实例,就能彻底消除代码重复啦。

第一步:创建自定义NavigationLink组件

我们可以定义一个名为HousemateNavigationLink的View,接收两个核心参数:室友数量housemateCount和背景渐变gradient(如果你的渐变是全局统一的,也可以把它设为默认值,不用每次传)。把你原来写的所有UI样式逻辑都移到这个自定义View里,只把变化的部分用参数替换:

struct HousemateNavigationLink: View {
    let housemateCount: Int
    let gradient: Gradient // 如果渐变是全局的,这里可以改成let gradient: Gradient = yourGlobalGradient
    
    var body: some View {
        NavigationLink(
            destination: FairRentView(
                viewModel: FairRentViewModel(Amounts(), housemates: housemateCount)
            )
        ) {
            Text("\(housemateCount)")
                .fontWeight(.bold)
                .font(.title)
                .lineLimit(0)
                .padding()
                .frame(minWidth: 0, maxWidth: 250, alignment: .center)
                .background(gradient)
                .foregroundColor(.white)
                .padding(2)
                .overlay(
                    RoundedRectangle(cornerRadius:20)
                        .stroke(gradient, lineWidth:15)
                )
                .overlay(
                    Image(systemName: "person.crop.circle.badge.plus")
                        .font(.largeTitle)
                        .padding(.leading)
                        .foregroundColor(.white)
                    , alignment: .leading)
                .padding(5)
        }
    }
}

第二步:在原View中复用自定义组件

现在你原来的重复代码可以直接替换成两行简洁的调用,完全达到复用效果:

// 假设你已经定义了gradient变量
HousemateNavigationLink(housemateCount: 1, gradient: gradient)
HousemateNavigationLink(housemateCount: 2, gradient: gradient)

额外优化:让组件更灵活

如果后续你需要修改某个细节(比如图标样式、圆角大小),只需要在HousemateNavigationLink里改一次,所有实例都会同步更新。要是以后需要支持不同的图标,还可以给组件加个可选参数:

// 新增可选参数,默认使用原来的图标
struct HousemateNavigationLink: View {
    let housemateCount: Int
    let gradient: Gradient
    private let iconName: String
    
    // 提供带默认图标的初始化方法
    init(housemateCount: Int, gradient: Gradient, iconName: String = "person.crop.circle.badge.plus") {
        self.housemateCount = housemateCount
        self.gradient = gradient
        self.iconName = iconName
    }
    
    var body: some View {
        NavigationLink(
            destination: FairRentView(
                viewModel: FairRentViewModel(Amounts(), housemates: housemateCount)
            )
        ) {
            Text("\(housemateCount)")
                .fontWeight(.bold)
                .font(.title)
                .lineLimit(0)
                .padding()
                .frame(minWidth: 0, maxWidth: 250, alignment: .center)
                .background(gradient)
                .foregroundColor(.white)
                .padding(2)
                .overlay(
                    RoundedRectangle(cornerRadius:20)
                        .stroke(gradient, lineWidth:15)
                )
                .overlay(
                    Image(systemName: iconName)
                        .font(.largeTitle)
                        .padding(.leading)
                        .foregroundColor(.white)
                    , alignment: .leading)
                .padding(5)
        }
    }
}

本质上,NavigationLink和Button一样都是SwiftUI的View类型,所以复用逻辑完全通用——只要把重复的View结构封装成自定义组件,通过参数传递变化的值,就能轻松实现代码复用啦。

内容的提问来源于stack exchange,提问作者Jordan1993

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:02:29