iOS17 SwiftUI MapKit:MapPolyline无法结合布尔控件实现加载控制
iOS 17 SwiftUI MapKit 路线加载时显示进度并禁用交互的解决方案
核心问题分析
- 原代码中
showProgress未被正确触发,始终为false,导致进度条不显示 - 多个路线请求是独立异步任务,无法统一判断全部任务的完成状态
- MapPolyline必须嵌套在Map闭包内,这是SwiftUI Map的API要求,无需强行重构
解决方案步骤
- 用TaskGroup管理所有异步任务:追踪所有路线请求的完成状态,确保所有路线加载完成后再隐藏进度条
- 正确控制进度条显示状态:开始加载前设置
showProgress = true,所有任务完成后设为false - 禁用地图交互:给Map添加
.disabled(showProgress)修饰符,加载期间禁止用户操作
修改后的完整代码
struct ContentView: View { @State private var routes = [MKRoute]() @State private var showProgress: Bool = false var body: some View { ZStack { Map() { if !routes.isEmpty { ForEach(routes, id: \.self) { route in MapPolyline(route) .stroke(.blue, lineWidth: 4) } } } .disabled(showProgress) // 加载时禁用交互 .onAppear { Task { await loadAllRoutes() } } // 进度条覆盖在地图上方 if showProgress { ProgressView() .tint(.red) .scaleEffect(4) .background(.black.opacity(0.5)) .cornerRadius(8) } } } func loadAllRoutes() async { showProgress = true defer { showProgress = false } // 所有任务完成后自动隐藏进度条 let lats: [CLLocationDegrees] = [ 37.338207, 38.5816, 39.1677, 40.760780 ] let longs: [CLLocationDegrees] = [ -121.886330, -121.4944, -120.1452, -111.891045 ] // 使用TaskGroup并行处理所有路线请求 await withTaskGroup(of: MKRoute?.self) { group in for r in 0..<3 { group.addTask { let request = MKDirections.Request() request.source = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: lats[r], longitude: longs[r]))) request.destination = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: lats[r + 1], longitude: longs[r + 1]))) do { let result = try await MKDirections(request: request).calculate() return result.routes.first } catch { print("路线请求失败: \(error.localizedDescription)") return nil } } } // 收集所有返回的路线 for await route in group { if let route { routes.append(route) } } } } }
关键改进点说明
- TaskGroup的使用:确保所有3个路线请求都完成后才隐藏进度条,避免部分路线加载完成就提前关闭进度
- defer语句:无论任务成功还是失败,都会执行
showProgress = false,防止进度条一直显示 - 禁用交互:
.disabled(showProgress)让地图在加载期间无法被用户操作,符合需求 - 错误处理:添加了do-catch捕获路线请求的错误,便于调试
内容的提问来源于stack exchange,提问作者JohnSF
相关产品推荐
相关产品推荐

