點擊MapView的調出註釋可見當用戶移動所述地圖畫面到其中銷靠近屏幕的邊緣處結束了,請觀察鏈接圖像(底部,下文)夫特 - 製作時銷註釋由用戶
和然後選擇該引腳註釋,然後Apple方法將地圖屏幕稍微向屏幕中心移動,以便引腳註釋標註可見。
我的問題是雙重的:
一,什麼蘋果方法被調用,以使該屏幕調整?
二,如果實現了MKMapViewDelegate擴展,在mapView didSelect視圖方法中實現相同功能的最明智的方法是什麼?
MapView的屏幕調節序列:
點擊MapView的調出註釋可見當用戶移動所述地圖畫面到其中銷靠近屏幕的邊緣處結束了,請觀察鏈接圖像(底部,下文)夫特 - 製作時銷註釋由用戶
和然後選擇該引腳註釋,然後Apple方法將地圖屏幕稍微向屏幕中心移動,以便引腳註釋標註可見。
我的問題是雙重的:
一,什麼蘋果方法被調用,以使該屏幕調整?
二,如果實現了MKMapViewDelegate擴展,在mapView didSelect視圖方法中實現相同功能的最明智的方法是什麼?
MapView的屏幕調節序列:
從理論上說,你可以得到註解視圖的框架,並檢查它是否是太靠近地圖視圖的邊緣:
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
// if view.frame is too close to the edges of the MKMapView, triggered your desired method
}
在實踐中,這是不可靠的,因爲它也取決於註釋視圖的標註泡泡。對於「過於接近邊緣」標準,我們需要一個不同的閾值,具體取決於標註泡泡的大小,因此沒有簡單的方法。
這是一個小黑客:當屏幕調整時,將調用regionWillChangeAnimated
方法。如果攻上批註的一秒鐘內觸發,有一個很好的機會,它是由用戶敲擊的註釋引起的:
weak var tappedAnnotationView: MKAnnotationView?
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
self.tappedAnnotationView = view // this property will only be non-nil for 0.1 seconds
DispatchQueue.global().asyncAfter(deadline: .now() + 0.1) {
self.tappedAnnotationView = nil
}
}
func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
if self.tappedAnnotationView != nil {
print("map adjusted due to tap on an annotation view")
}
}
它適用於我在它扔了基本的測試,但顯然有將會是極端的情況,因爲它是一種黑客攻擊。
我想出如下:
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
// Get Coordinate for Selected Map Pin
let selectedPinCoordinate = (view.annotation?.coordinate)!
// Determine (X,Y) coordinates for Selected Map Pin on view (mapView)
let SelectedPinMapPoint = mapView.convert(selectedPinCoordinate, toPointTo: mapView)
// Determine (X,Y) coordinate for center point of view (mapView)
let mapCenterMapPoint = mapView.convert(mapView.centerCoordinate, toPointTo: mapView)
// Define an inner view within the existing view frame. Any Selected Map Pin outside
// bounds of inner view is deemed to be too close to the edge of the map for the callout
// to be fully viewable by the user
let innerRectFrameMinX = mapView.frame.maxX * 0.15
let innerRectFrameMaxX = mapView.frame.maxX * 0.85
let innerRectFrameMinY = mapView.frame.maxY * 0.30
let innerRectFrameMaxY = mapView.frame.maxY * 0.85
// Create a variable which will serve as the new center (X,Y) coordinate
var newCenter = CGPoint()
// Default new center (X,Y) coordinate to current view (X,Y) coordinate
newCenter.x = mapCenterMapPoint.x
newCenter.y = mapCenterMapPoint.y
// Determine if x coordinate of Selected Map Pin is outside bounds. If so,
// set a new center x coordinate so callout can be clearly seen by the user
switch (SelectedPinMapPoint.x) {
case _ where (SelectedPinMapPoint.x < innerRectFrameMinX):
newCenter.x = mapView.frame.midX - (innerRectFrameMinX - SelectedPinMapPoint.x)
case _ where (SelectedPinMapPoint.x > innerRectFrameMaxX):
newCenter.x = mapView.frame.midX + (SelectedPinMapPoint.x - innerRectFrameMaxX)
default: break
}
// Determine if y coordinate of Selected Map Pin is outside bounds. If so,
// set a new center y coordinate so callout can be clearly seen by the user
switch (SelectedPinMapPoint.y) {
case _ where (SelectedPinMapPoint.y < innerRectFrameMinY):
newCenter.y = mapView.frame.midY - (innerRectFrameMinY - SelectedPinMapPoint.y)
case _ where (SelectedPinMapPoint.y > innerRectFrameMaxY):
newCenter.y = mapView.frame.midY + (SelectedPinMapPoint.y - innerRectFrameMaxY)
default: break
}
// Convert new map Center (X,Y) coordinate to map coordinate
let newCenterCoordinate = mapView.convert(newCenter, toCoordinateFrom: nil)
// Set new center as center for map view
mapView.setCenter(newCenterCoordinate, animated: true)
}
我聯繫我的構想任何益處,可以提供一個粗略的圖形草圖。 Rough Graphical Sketch
感謝您花時間回覆。我很感激。 –