夫特 - 制作时销注释由用户
问题描述:
点击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
感谢您花时间回复。我很感激。 –