如何将两个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
相关产品推荐
相关产品推荐

