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

如何将两个Switch语句合并为单个函数优化SwiftUI代码?

Swift地图标注代码优化方案

一、合并两个Switch函数的实现方式

核心思路是用结构体封装每个分类对应的颜色和图标,通过一次Switch判断返回完整配置,避免重复的分支判断逻辑。

1. 定义配置结构体

先创建一个结构体来统一管理标注的颜色和图标信息:

struct AnnotationConfig {
    let colorHex: String
    let iconName: String
}

2. 实现单函数返回配置

替换原来的两个Switch函数,用单个函数返回完整的标注配置:

private func annotationConfig(for category: String) -> AnnotationConfig {
    switch category {
    case "Route":
        return AnnotationConfig(colorHex: "#6A798E", iconName: "car-side")
    case "Scenic Area":
        return AnnotationConfig(colorHex: "#006994", iconName: "camera")
    case "Attraction":
        return AnnotationConfig(colorHex: "#00954C", iconName: "people-group")
    case "Hospitality":
        return AnnotationConfig(colorHex: "#6D5B97", iconName: "bed")
    case "Landmark":
        return AnnotationConfig(colorHex: "#5D5639", iconName: "landmark-flag")
    default:
        return AnnotationConfig(colorHex: "#FFFFFF", iconName: "NA")
    }
}

3. 修改视图调用逻辑

在viewForPlace中一次性获取配置,简化代码:

@ViewBuilder func viewForPlace(_ place: Place) -> some View {
    // 提前获取当前地点的标注配置
    let config = annotationConfig(for: place.category)
    
    Image("map-pin")
        .renderingMode(.template)
        .resizable()
        .frame(width: 35, height: 35)
        .foregroundColor(place.show ? .red : Color(UIColor(hexString: config.colorHex)))
        .onTapGesture {
            guard !place.show else { return }
            tapOnMapAnnotation(place: place)
        }
        .overlay(
            Image(config.iconName)
                .renderingMode(.template)
                .resizable()
                .frame(width: 10, height: 8)
                .foregroundColor(.white)
                .padding(.bottom, 15)
        )
}

二、进一步优化:提升性能与类型安全

如果要追求更好的性能和代码健壮性,推荐用枚举代替字符串分类,避免字符串拼写错误,同时枚举的分支匹配效率比字符串更高。

1. 定义分类枚举

把字符串分类转成枚举类型,并给Place添加扩展方便转换:

enum PlaceCategory: String {
    case route = "Route"
    case scenicArea = "Scenic Area"
    case attraction = "Attraction"
    case hospitality = "Hospitality"
    case landmark = "Landmark"
    case unknown
}

extension Place {
    var categoryEnum: PlaceCategory {
        PlaceCategory(rawValue: category) ?? .unknown
    }
}

2. 适配枚举的配置函数

修改配置函数接收枚举参数,编译时会自动检查是否覆盖所有分支,避免遗漏:

private func annotationConfig(for category: PlaceCategory) -> AnnotationConfig {
    switch category {
    case .route:
        return AnnotationConfig(colorHex: "#6A798E", iconName: "car-side")
    case .scenicArea:
        return AnnotationConfig(colorHex: "#006994", iconName: "camera")
    case .attraction:
        return AnnotationConfig(colorHex: "#00954C", iconName: "people-group")
    case .hospitality:
        return AnnotationConfig(colorHex: "#6D5B97", iconName: "bed")
    case .landmark:
        return AnnotationConfig(colorHex: "#5D5639", iconName: "landmark-flag")
    case .unknown:
        return AnnotationConfig(colorHex: "#FFFFFF", iconName: "NA")
    }
}

3. 优化颜色创建性能

如果地图标注数量较多,每次创建UIColor会有额外开销,可以提前预加载颜色:

// 预定义所有标注颜色
private enum AnnotationColors {
    static let route = Color(UIColor(hexString: "#6A798E"))
    static let scenicArea = Color(UIColor(hexString: "#006994"))
    static let attraction = Color(UIColor(hexString: "#00954C"))
    static let hospitality = Color(UIColor(hexString: "#6D5B97"))
    static let landmark = Color(UIColor(hexString: "#5D5639"))
    static let unknown = Color.white
}

// 修改配置结构体直接存储Color
struct AnnotationConfig {
    let color: Color
    let iconName: String
}

// 适配后的配置函数
private func annotationConfig(for category: PlaceCategory) -> AnnotationConfig {
    switch category {
    case .route:
        return AnnotationConfig(color: AnnotationColors.route, iconName: "car-side")
    case .scenicArea:
        return AnnotationConfig(color: AnnotationColors.scenicArea, iconName: "camera")
    case .attraction:
        return AnnotationConfig(color: AnnotationColors.attraction, iconName: "people-group")
    case .hospitality:
        return AnnotationConfig(color: AnnotationColors.hospitality, iconName: "bed")
    case .landmark:
        return AnnotationConfig(color: AnnotationColors.landmark, iconName: "landmark-flag")
    case .unknown:
        return AnnotationConfig(color: AnnotationColors.unknown, iconName: "NA")
    }
}

这样修改后,颜色只会初始化一次,避免重复创建UIColor实例,提升渲染性能。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:05:39