我正在尝试使用一个UIGestureReconizers
和一个MKMapView
,用户可以放置一个引脚并拖动它。它有一个callout
。我是在TabbarController
以及NavigationController
内实施的。我目前有:
1)PanGestureRecognizer
激活屏幕上的Tabbar和Navigation项目。这样可以正常工作而不会干扰平移地图。
2)设置为一次点击的TapGestureRecognizer
会将1)中的两个项目设置回屏幕。
3)设置为两次点按的TapGestureRecognizer
允许基础MKMapView
缩放功能正常工作。此GestureRecognizer's
delegate
具有gestureRecognizer。shouldRecognizeSimultaneouslyWithGestureRecognizer
设置为true
这些设置在viewDidLoad
中,如下所示:
// This sets up the pan gesture recognizer to hide the bars from the UI.
let panRec: UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: "didDragMap:")
panRec.delegate = self
mapView.addGestureRecognizer(panRec)
// This sets up the tap gesture recognizer to un-hide the bars from the UI.
let singleTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "didTapMap:")
singleTap.delegate = self
singleTap.numberOfTapsRequired = 1
singleTap.numberOfTouchesRequired = 1
mapView.addGestureRecognizer(singleTap)
// This sets up the double tap gesture recognizer to enable the zoom facility.
// In order to pass double-taps to the underlying `MKMapView` the delegate for this recognizer (self) needs to return true from
// gestureRecognizer.shouldRecognizeSimultaneouslyWithGestureRecognizer
let doubleTap: UITapGestureRecognizer = UITapGestureRecognizer()
doubleTap.numberOfTapsRequired = 2
doubleTap.numberOfTouchesRequired = 1
doubleTap.delegate = self
mapView.addGestureRecognizer(doubleTap)
// This delays the single-tap recognizer slightly and ensures that it will NOT fire if there is a double-tap
singleTap.requireGestureRecognizerToFail(doubleTap)
当我尝试实现UILongPressGestureRecognizer
以允许将引脚放到地图上时,会出现问题。我正在尝试将以下内容添加到viewDidLoad
:
// This sets up the long tap to drop the pin.
let longTap: UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "didLongTapMap:")
longTap.delegate = self
longTap.numberOfTapsRequired = 0
longTap.minimumPressDuration = 0.5
mapView.addGestureRecognizer(longTap)
这是我的行动方法:
func didLongTapMap(gestureRecognizer: UIGestureRecognizer) {
// Get the spot that was tapped.
let tapPoint: CGPoint = gestureRecognizer.locationInView(mapView)
let touchMapCoordinate: CLLocationCoordinate2D = mapView.convertPoint(tapPoint, toCoordinateFromView: mapView)
var viewAtBottomOfHierarchy: UIView = mapView.hitTest(tapPoint, withEvent: nil)
if let viewAtBottom = viewAtBottomOfHierarchy as? MKPinAnnotationView {
return
} else {
if .Began == gestureRecognizer.state {
// Delete any existing annotations.
if mapView.annotations.count != 0 {
mapView.removeAnnotations(mapView.annotations)
}
annotation = MKPointAnnotation()
annotation.coordinate = touchMapCoordinate
mapView.addAnnotation(annotation)
_isPinOnMap = true
findAddressFromCoordinate(annotation.coordinate)
updateLabels()
}
}
}
这确实允许在长敲击时放下引脚,并且单击将显示标注但是如果拖动没有足够快地启动则第二次敲击以保持并拖动导致第二引脚掉落。第二个引脚落入前一个引脚悬停的空间,并且可以被用户拖动,但是新的引脚丢失看起来很笨拙。
我正在尝试使用该行:
if let viewAtBottom = viewAtBottomOfHierarchy as? MKPinAnnotationView {
将tap返回到MKMapView
并阻止另一个引脚被删除但是返回永远不会被调用,即使此行上的断点显示viewAtBottom属于MapKit.MKPinAnnotationView
类型。我出错的任何想法?
答案 0 :(得分:1)
如果我理解正确,我想我可能会找到你问题的答案。 当一个引脚掉落然后在不放置另一个引脚的情况下拖动屏幕时出现问题,对吗? 这是我的代码,我一直在做类似的东西,这似乎对我有用。 导入UIKit 导入MapKit 导入CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
@IBOutlet var map: MKMapView!
var manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let uilpgr = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longpress(gestureRecognizer:)))
uilpgr.minimumPressDuration = 2
map.addGestureRecognizer(uilpgr)
if activePlace == -1 {
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
self.map.showsUserLocation = true
} else {
//GET PLACE DETAILS TO DISPLAY ON MAP
if places.count > activePlace {
if let name = places[activePlace]["name"]{
if let lat = places[activePlace]["lat"]{
if let lon = places[activePlace]["lon"]{
if let latitude = Double(lat) {
if let longitude = Double(lon) {
let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let region = MKCoordinateRegionMake(coordinate, span)
self.map.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
annotation.title = name
self.map.addAnnotation(annotation)
}
}
}
}
}
}
}
}
func longpress(gestureRecognizer: UIGestureRecognizer) {
if gestureRecognizer.state == UIGestureRecognizerState.began {
let touchPoint = gestureRecognizer.location(in: self.map)
let newCoordinate = self.map.convert(touchPoint, toCoordinateFrom: self.map)
let location = CLLocation(latitude: newCoordinate.latitude, longitude: newCoordinate.longitude)
var title = ""
CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, error) in
if error != nil {
print(error)
} else {
if let placemark = placemarks?[0] {
if placemark.subThoroughfare != nil {
title += placemark.subThoroughfare! + " "
}
if placemark.thoroughfare != nil {
title += placemark.thoroughfare! + " "
}
}
}
if title == "" {
title = "Added \(NSDate())"
}
let annotation = MKPointAnnotation()
annotation.coordinate = newCoordinate
annotation.title = title
self.map.addAnnotation(annotation)
places.append(["name": title, "lat":String(newCoordinate.latitude), "lon":String(newCoordinate.longitude)])
UserDefaults.standard.set(places, forKey: "places")
})
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = CLLocationCoordinate2D(latitude: locations[0].coordinate.latitude, longitude: locations[0].coordinate.longitude)
let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
let region = MKCoordinateRegion(center: location, span: span)
self.map.setRegion(region, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
希望它有所帮助,问题也可能是您的最小长按持续时间仅为0.5。