swift 当Map跨度为0.1时,如何显示Map注解?

6ljaweal  于 2023-02-03  发布在  Swift
关注(0)|答案(2)|浏览(163)

Map跨度为0.1时如何显示Map注记?我希望在Map跨度〈= 0.1之前不显示Map大头针

struct City: Identifiable {
    let id = UUID()
    let name: String
    let coordinate: CLLocationCoordinate2D
}

struct ContentView: View {
    @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10))

    let annotations = [
        City(name: "London", coordinate: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275)),
        City(name: "Paris", coordinate: CLLocationCoordinate2D(latitude: 48.8567, longitude: 2.3508)),
        City(name: "Rome", coordinate: CLLocationCoordinate2D(latitude: 41.9, longitude: 12.5)),
        City(name: "Washington DC", coordinate: CLLocationCoordinate2D(latitude: 38.895111, longitude: -77.036667))
    ]

    var body: some View {
        Map(coordinateRegion: $region, annotationItems: annotations) {
            MapPin(coordinate: $0.coordinate)
        }
        .frame(width: 400, height: 300)
    }
}

如何才能做到这一点?

dzhpxtsq

dzhpxtsq1#

不能使用MapPin,因为它是protocol的类型,而不是View的类型。您可以使用MapAnnotation来代替它。因为您的region参数绑定了视图,所以您可以检查Map跨度并显示/隐藏注解,如下所示;

Map(coordinateRegion: $region, annotationItems: annotations) {
    MapAnnotation(coordinate: $0.coordinate) {
        // Use whatever value instead of 2.5
        if region.span.latitudeDelta < 2.5 {
            Image(systemName: "mappin")
                .resizable()
                .frame(width: 18, height: 36)
                .foregroundColor(Color.red)
        } else {
            EmptyView()
        }
    }
}
.frame(width: 400, height: 300)
2q5ifsrm

2q5ifsrm2#

您可以使用一个计算变量,当span正确时返回true,然后有条件地让Map使用注解。

struct SuperZoomMap: View {
    @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10))

    let annotations = [
        City(name: "London", coordinate: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275)),
        City(name: "Paris", coordinate: CLLocationCoordinate2D(latitude: 48.8567, longitude: 2.3508)),
        City(name: "Rome", coordinate: CLLocationCoordinate2D(latitude: 41.9, longitude: 12.5)),
        City(name: "Washington DC", coordinate: CLLocationCoordinate2D(latitude: 38.895111, longitude: -77.036667))
    ]
    ///Returns true when the
    ///region.span.latitudeDelta <= 0.1 || region.span.longitudeDelta <= 0.1
    var show: Bool{
        if region.span.latitudeDelta <= 0.1 || region.span.longitudeDelta <= 0.1{
            return true
        }else{
            return false
        }
    }

    var body: some View {
        VStack{
            Text(region.span.latitudeDelta, format: .number)
            Text(region.span.longitudeDelta, format: .number)
            Map(coordinateRegion: $region, annotationItems: show ? annotations : []) {
                MapPin(coordinate: $0.coordinate)
            }
            .frame(width: 400, height: 300)
        }
    }
}

也可以使用CLLocation s distance过滤端号,以便仅打印中心/可见端号特定距离内的端号。
例如,如果你放大到伦敦,排除巴黎,罗马和华盛顿特区。

struct SuperZoomMap: View {
    @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10))

    let annotations = [
        City(name: "London", coordinate: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275)),
        City(name: "Paris", coordinate: CLLocationCoordinate2D(latitude: 48.8567, longitude: 2.3508)),
        City(name: "Rome", coordinate: CLLocationCoordinate2D(latitude: 41.9, longitude: 12.5)),
        City(name: "Washington DC", coordinate: CLLocationCoordinate2D(latitude: 38.895111, longitude: -77.036667))
    ]
    ///Returns true when the
    ///region.span.latitudeDelta <= 0.1 || region.span.longitudeDelta <= 0.1
    var show: Bool{
        if region.span.latitudeDelta <= 0.1 || region.span.longitudeDelta <= 0.1{
            return true
        }else{
            return false
        }
    }
    //Only show the pins within 10000 meters from the center 
    var filtered: [City]{
        guard show else {
            return []
        }
        return annotations.filter { city in
            let c = CLLocation(latitude: city.coordinate.latitude, longitude: city.coordinate.longitude)
            let current = CLLocation(latitude: region.center.latitude, longitude: region.center.longitude)
            
            return c.distance(from: current) <= 10000
        }
    }
    var body: some View {
        VStack{
            Text(filtered.count, format: .number)
            Text(region.span.latitudeDelta, format: .number)
            Text(region.span.longitudeDelta, format: .number)
            Map(coordinateRegion: $region, annotationItems: filtered) {
                MapPin(coordinate: $0.coordinate)
            }
            .frame(width: 400, height: 300)
        }
    }
}

相关问题