在点击和MKMapView上显示注解的标注之间几乎有0.5秒的延迟。有人知道为什么会这样吗?我如何让它在用户点击Map时立即做出响应?即使用户位置注解在点击时在标注中显示“当前位置”,也会发生这种情况。我希望它在点击时立即显示,没有奇怪的延迟。编辑:我认为这是由于didSelectAnnotationView调用的setSelected函数。setSelected有一个“animated”属性,可能会减慢它的速度。我如何消除这个动画?
v440hwme1#
在做了大量的研究之后,我找到了一个解决这个问题的方法!它有点古怪,但它的工作就像一个魅力。秘密是,当关闭Map的缩放时,didSelect监听器会立即触发。当我们需要缩放时(当然),我们需要做的是,暂时禁用缩放,就在didSelect事件发生的那一刻!在Swift中:
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:))) gestureRecognizer.numberOfTapsRequired = 1 gestureRecognizer.numberOfTouchesRequired = 1 gestureRecognizer.delegate = self mapView.addGestureRecognizer(gestureRecognizer)
以及
@objc func handleTap(_ sender: UITapGestureRecognizer? = nil) { // disabling zoom, so the didSelect triggers immediately mapView.isZoomEnabled = false DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { self.mapView.isZoomEnabled = true } }
这个手势事件在didSelect事件之前触发,所以当didSelect事件被调用时,缩放被关闭,并且它没有延迟地触发!
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { mapView.isZoomEnabled = true // Not really necessary // Triggered immediately, do something }
注意:这会禁用Map的双击手势,但我猜它们不会用得太多。所以如果你想要快速响应,你需要接受它!
vsaztqbk2#
遗憾的是,您对此无能为力。这与在移动的Safari中点击链接速度慢的原因完全相同:手势识别器不得不在它们同意你正在敲击之前拥挤一会儿以确定你是否可能正在滚动(拖动)。所以,这与动画无关。这只是在这种情况下手势识别的本质。
ycl3bljg3#
我的解决方案是在MKAnnotationView子类上启用Map缩放并添加单独的tap处理程序。本机缩放MKOneHandedZoomGestureRecognizer、MKZoomingPanGestureRecognizer和MKConditionalPanZoomGestureRecognizer将正常工作。而且点击时的即时React将由注解视图上的按钮或点击识别器处理。
wribegjk4#
@tobidude的回答奏效了,不过还可以稍微改进一下。不要把TapGestureRecognizer添加到Map视图中,而是在初始化时把它添加到AnnotationView子类中。这样,你就不必忽略Map视图上的所有双击。在Swift 5中:
override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) clusteringIdentifier = MKMapViewDefaultClusterAnnotationViewReuseIdentifier setupGestureRecognizerToPreventInteractionDelay() }
然后:
private func setupGestureRecognizerToPreventInteractionDelay() { let quickSelectGestureRecognizer = UITapGestureRecognizer() quickSelectGestureRecognizer.delaysTouchesBegan = false quickSelectGestureRecognizer.delaysTouchesEnded = false quickSelectGestureRecognizer.numberOfTapsRequired = 1 quickSelectGestureRecognizer.numberOfTouchesRequired = 1 quickSelectGestureRecognizer.delegate = self self.addGestureRecognizer(quickSelectGestureRecognizer) }
最后:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { mapView?.isZoomEnabled = false DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { self.mapView?.isZoomEnabled = true } return false }
5uzkadbs5#
这里是相同的想法与缩放禁用/启用,在一个更完整的解决方案与正确的代理模式。1.定义代理协议并修改自定义AnnotationView的init以设置点击手势。
// MyAnnotationView.swift: protocol MyAnnotationViewDelegate: class { func didSelect(myAnnotationView: MyAnnotationView) } class MyAnnotationView: MKAnnotationView { weak var delegate: MyAnnotationViewDelegate? override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) setupGestureRecognizer() } private func setupGestureRecognizer() { let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapGestureTapped)) tapGesture.delaysTouchesBegan = false tapGesture.delaysTouchesEnded = false addGestureRecognizer(tapGesture) } @objc func tapGestureTapped(_ sender: AnyObject) { delegate?.didSelect(myAnnotationView: self) } }
1.设置委托
// MapViewController.swift extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { guard let annotation = annotation as? MyAnnotation else { return nil } let view = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as? MyAnnotationView view?.delegate = self // <-- return view } }
1.符合我的注解视图委托
// MapViewController.swift extension MapViewController: MyAnnotationViewDelegate { func didSelect(MyAnnotationView: MyAnnotationView) { mapView.isZoomEnabled = false DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { self.mapView?.isZoomEnabled = true } } }
5条答案
按热度按时间v440hwme1#
在做了大量的研究之后,我找到了一个解决这个问题的方法!它有点古怪,但它的工作就像一个魅力。
秘密是,当关闭Map的缩放时,didSelect监听器会立即触发。当我们需要缩放时(当然),我们需要做的是,暂时禁用缩放,就在didSelect事件发生的那一刻!
在Swift中:
以及
这个手势事件在didSelect事件之前触发,所以当didSelect事件被调用时,缩放被关闭,并且它没有延迟地触发!
注意:这会禁用Map的双击手势,但我猜它们不会用得太多。所以如果你想要快速响应,你需要接受它!
vsaztqbk2#
遗憾的是,您对此无能为力。这与在移动的Safari中点击链接速度慢的原因完全相同:手势识别器不得不在它们同意你正在敲击之前拥挤一会儿以确定你是否可能正在滚动(拖动)。
所以,这与动画无关。这只是在这种情况下手势识别的本质。
ycl3bljg3#
我的解决方案是在MKAnnotationView子类上启用Map缩放并添加单独的tap处理程序。
本机缩放MKOneHandedZoomGestureRecognizer、MKZoomingPanGestureRecognizer和MKConditionalPanZoomGestureRecognizer将正常工作。
而且点击时的即时React将由注解视图上的按钮或点击识别器处理。
wribegjk4#
@tobidude的回答奏效了,不过还可以稍微改进一下。
不要把TapGestureRecognizer添加到Map视图中,而是在初始化时把它添加到AnnotationView子类中。这样,你就不必忽略Map视图上的所有双击。
在Swift 5中:
然后:
最后:
5uzkadbs5#
这里是相同的想法与缩放禁用/启用,在一个更完整的解决方案与正确的代理模式。
1.定义代理协议并修改自定义AnnotationView的init以设置点击手势。
1.设置委托
1.符合我的注解视图委托