iOS17 SwiftUI MapKit迁移问题:Marker选中无法跳转详情页
iOS17 MapKit迁移后无法触发导航跳转
问题背景
原代码使用MapAnnotation实现地图标注点击跳转详情页,在iOS17下触发弃用警告,改用Marker和Map的selection绑定后,选中标记有动画但无法跳转至DestinationDetailView。
原代码(iOS17前)
NavigationStack { Map(coordinateRegion: $mapRegion, annotationItems: destinations) { destination in MapAnnotation(coordinate: destination.coordinate) { NavigationLink { DestinationDetailView(destination: destination) } label: { VStack { Image(systemName: "\(destination.locationType.attributes.icon)") .font(.largeTitle) .foregroundColor(destination.locationType.attributes.color) Text("\(destination.name)") .foregroundColor(.black) .font(.subheadline) } } } } }
修改后的代码(iOS17)
NavigationStack { Map(position: $position, selection: $mapSelection) { ForEach(destinations, id: \.locationId) { destination in Marker(destination.name, coordinate: destination.coordinate) .tint(destination.locationType.attributes.color) .tag(destination) } } .onChange(of: mapSelection) { oldValue, newValue in if mapSelection != nil { print("Selection: \(mapSelection!.name)") NavigationLink("",destination: DestinationDetailView(destination: mapSelection!)) } } }
问题原因
你在onChange回调里创建NavigationLink的方式无效——SwiftUI的视图必须存在于视图层级树中,回调里动态生成的NavigationLink不会被添加到界面结构里,自然无法触发导航动作。
解决方法
推荐使用iOS17新增的navigationDestination修饰符,直接关联选中的标注数据:
NavigationStack { Map(position: $position, selection: $mapSelection) { ForEach(destinations, id: \.locationId) { destination in Marker(destination.name, coordinate: destination.coordinate) .tint(destination.locationType.attributes.color) .tag(destination) } } // 匹配Destination类型,自动处理跳转 .navigationDestination(for: Destination.self) { selectedDestination in DestinationDetailView(destination: selectedDestination) } }
或者也可以给NavigationStack直接绑定selection参数,配合navigationDestination:
NavigationStack(selection: $mapSelection) { Map(position: $position, selection: $mapSelection) { ForEach(destinations, id: \.locationId) { destination in Marker(destination.name, coordinate: destination.coordinate) .tint(destination.locationType.attributes.color) .tag(destination) } } .navigationDestination(item: $mapSelection) { selectedDestination in DestinationDetailView(destination: selectedDestination) } }
两种方式都能在mapSelection被选中时,自动触发导航跳转至详情页,无需手动在回调里处理。
内容的提问来源于stack exchange,提问作者Torsten
相关产品推荐
相关产品推荐

