gpt4 book ai didi

ios - 如何获得可无延迟拖动的 MKAnnotationView?

转载 作者:行者123 更新时间:2023-11-29 05:18:33 24 4
gpt4 key购买 nike

下面的代码可以工作并给我一个可拖动的注释 View 。但是,我注意到注释 View 从一开始就不可拖动,而是只能在手指在注释 View 上停留一小会儿之后才可拖动。当直接进行拖动移动时,拖动不会影响注释 View ,而是平移 map 。它当然不像拖放。在设备上和模拟器中都可以。

ViewController(MapView 的委托(delegate))

override func viewDidLoad() {
/// ...
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(addPin))
mapView.addGestureRecognizer(gestureRecognizer)
}

func addPin(gestureRecognizer: UIGestureRecognizer) {
if gestureRecognizer.state != UIGestureRecognizerState.Began {
return
}
for annotation in mapView.annotations {
mapView.removeAnnotation(annotation)
}
let touchLocationInView = gestureRecognizer.locationInView(mapView)
let coordinate = mapView.convertPoint(touchLocationInView, toCoordinateFromView: mapView)
let annotation = DragAnnotation(coordinate: coordinate, title: "draggable", subtitle: "")
mapView.addAnnotation(annotation)
}

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isKindOfClass(DragAnnotation) {
let reuseIdentifier = "DragAnnotationIdentifier"
var annotationView: MKAnnotationView!
if let dequeued = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseIdentifier) {
annotationView = dequeued
} else {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
annotationView.annotation = annotation
annotationView.image = UIImage(named: "bluedisk2")
annotationView.canShowCallout = false
annotationView.draggable = true
return annotationView
}
return nil
}

func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
switch (newState) {
case .Starting:
view.dragState = .Dragging
case .Ending, .Canceling:
view.dragState = .None
default: break
}
}

拖动注释

import UIKit
import MapKit

class DragAnnotation : NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D {
didSet {
print(coordinate)
}
}
var title: String?
var subtitle: String?

init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String) {
self.coordinate = coordinate
self.title = title
self.subtitle = subtitle
}
}

最佳答案

我认为您无法更改可拖动延迟,但您可以禁用它并添加自己的无延迟(或更短延迟)的拖动手势:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation { return nil }

var view = mapView.dequeueReusableAnnotationViewWithIdentifier("Foo")
if view == nil {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "Foo")
view?.draggable = false

let drag = UILongPressGestureRecognizer(target: self, action: #selector(handleDrag(_:)))
drag.minimumPressDuration = 0 // set this to whatever you want
drag.allowableMovement = .max
view?.addGestureRecognizer(drag)
} else {
view?.annotation = annotation
}

return view
}

private var startLocation = CGPointZero

func handleDrag(gesture: UILongPressGestureRecognizer) {
let location = gesture.locationInView(mapView)

if gesture.state == .Began {
startLocation = location
} else if gesture.state == .Changed {
gesture.view?.transform = CGAffineTransformMakeTranslation(location.x - startLocation.x, location.y - startLocation.y)
} else if gesture.state == .Ended || gesture.state == .Cancelled {
let annotationView = gesture.view as! MKAnnotationView
let annotation = annotationView.annotation as! DragAnnotation

let translate = CGPoint(x: location.x - startLocation.x, y: location.y - startLocation.y)
let originalLocation = mapView.convertCoordinate(annotation.coordinate, toPointToView: mapView)
let updatedLocation = CGPoint(x: originalLocation.x + translate.x, y: originalLocation.y + translate.y)

annotationView.transform = CGAffineTransformIdentity
annotation.coordinate = mapView.convertPoint(updatedLocation, toCoordinateFromView: mapView)
}
}

顺便说一句,如果您要更改注释的坐标,您需要将dynamic关键字添加到您的自定义类coefficient 声明,以便发出适当的 KVO 通知。

class DragAnnotation: NSObject, MKAnnotation {
dynamic var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?

init(coordinate: CLLocationCoordinate2D, title: String? = nil, subtitle: String? = nil) {
self.coordinate = coordinate
self.title = title
self.subtitle = subtitle
super.init()
}
}

请注意,在本例中,我将延迟设置为零。这意味着,如果您点击注释(“显示标注”的典型 UI),这可能会阻止其正常工作。它将将此视为非常短的阻力。这就是为什么标准 UI 需要在拖动之前延迟长按的原因。

因此,出于这个原因,我个人会犹豫是否要覆盖上面显示的此行为,因为它与最终用户熟悉的标准 map 行为不同。如果您的 map 的行为与用户设备上的任何其他 map 不同,这可能会让人感到沮丧。

关于ios - 如何获得可无延迟拖动的 MKAnnotationView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58921095/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com