-1

所以我想在单击注释时从图像 1 转到图像 2(Mapbox):

https://i.stack.imgur.com/OFIFa.png

通过在 Mapbox 委托函数之一中调用 mapView.setCenter() 将地图中心放在注释上相当容易,如下所示:

func mapView(_ mapView: MGLMapView, didSelect annotation: MGLAnnotation) {
    mapView.setCenter(annotation.coordinate, animated: true)
}

显然,这会将注释居中到屏幕的中间,但我需要将注释“居中”到弹出的视图上方的区域中,以便它仍然可见(理想情况下,它与 ' 的顶部等距查看'和屏幕的顶部边缘)。

我正在考虑在 setCenter 中设置 zoomLevel,然后缩放到注释以南的特定距离,但问题是 iOS 设备上的各种屏幕尺寸将使注释居中不同。

我也在想也许我可以在屏幕上进行某种从地图到 CGPoint 的坐标转换,但我真的不确定如何正确实现这一点(我只使用过 mapView.convert(CGPoint,toCoordinateFrom: mapView),这在这里没有用)。我不确定如何解决这个问题。任何帮助都将不胜感激,无论是让我开始走上一条道路,还是您已经有了更好的解决方案。谢谢!

4

2 回答 2

1

您可以将地图框的大小调整为该正方形,然后将坐标居中。这意味着视图将不再弹出在地图视图上,尽管它看起来会。

这可以通过以下方式完成:

(your MKMapView).frame = CGRect(x: , y: , width: , height: )

x 和 y 是超级视图(mapview 后面的视图)坐标系中的起始坐标。然后宽度和高度参数创建一个矩形,其尺寸从 x 和 y 开始。注意起点,有时在左下角,有时在左上角,视情况而定。根据您的实现,您可能还必须修改弹出视图框架。

- 如果您的地图始终连接到您可以使用的屏幕顶部

(your MKMapView).frame = CGRect(x: self.view.origin.x, y: self.view.origin.y, width: self.view.frame.width, height: self.view.frame.height/2)
于 2022-01-16T21:34:10.040 回答
1

我不使用 MapBox 但如果您可以访问该区域的跨度(地图的水平和垂直距离)

您可以从注记的坐标中减去所需的纬度跨度量,并为地图设置该中心。

    ///Centers the map region by placing the passed annotation in the center of the I quadrant
    func centerTop(annotation: SpecialAnnot){
        //Find a 4th of the span (The horizontal and vertical span representing the amount of map to display.)
        let latCorrection = region.span.latitudeDelta/4 + region.span.latitudeDelta/8
        
        self.region = MKCoordinateRegion(center: .init(latitude: annotation.coordinate.latitude - latCorrection, longitude: annotation.coordinate.longitude), span: region.span)
    }

这是一些 SwiftUI 代码。

import SwiftUI
import MapKit
class SpecialAnnot: NSObject, MKAnnotation, Identifiable{
    let id: UUID = .init()
    var coordinate: CLLocationCoordinate2D
    init(coordinate: CLLocationCoordinate2D) {
        self.coordinate = coordinate
        super.init()
    }
    
}
struct QuarterCenteredView: View {
    @State var region: MKCoordinateRegion = MKCoordinateRegion()
    
    let annotationCoordinate: [SpecialAnnot] = [SpecialAnnot(coordinate: .init(latitude: 40.748817, longitude: -73.985428))]
    var body: some View {
        VStack{
            Button("center quadrant I", action: {
                centerTop(annotation: annotationCoordinate.first!)
            })
            Map(coordinateRegion: $region, annotationItems: annotationCoordinate, annotationContent: { annot in
                MapAnnotation(coordinate: annot.coordinate, content: {
                    Image(systemName: "mappin").foregroundColor(.red)
                })
            })
                .onAppear(perform: {
                    DispatchQueue.main.async {
                        region = MKCoordinateRegion(center: annotationCoordinate.first!.coordinate, span: region.span)
                    }
                })
        }
    }
    ///Centers the map region by placing the passed annotation in the center of the I quadrant
    func centerTop(annotation: SpecialAnnot){
        //Find a 4th of the span (The horizontal and vertical span representing the amount of map to display.)
        let latCorrection = region.span.latitudeDelta/4 + region.span.latitudeDelta/8
        
        self.region = MKCoordinateRegion(center: .init(latitude: annotation.coordinate.latitude - latCorrection, longitude: annotation.coordinate.longitude), span: region.span)
    }
}

struct QuarterCenteredView_Previews: PreviewProvider {
    static var previews: some View {
        QuarterCenteredView()
    }
}
于 2022-01-16T22:53:29.753 回答