2014-07-16 2 views
7

UIGestureReconizers의 번호를 MKMapView과 함께 사용하려고하는데 사용자가 핀을 내려 놓고 드래그 할 수 있습니다. 그것은 callout 있습니다. 나는 이것을 TabbarControllerNavigationController에 구현하고 있습니다. 현재 가지고있는 항목은 다음과 같습니다.MKMapKit을 사용한 스위프트 제스처 인식기 - 핀 및 드래그를 놓으십시오.

1) PanGestureRecognizer은 Tabbar 및 Navigation 항목을 화면에서 움직입니다. 지도를 패닝하지 않고도 정상적으로 작동합니다.

2) 한 탭으로 설정된 TapGestureRecognizer은 두 항목을 1) 화면에서 다시 움직입니다.

3) TapGestureRecognizer을 두 번 탭으로 설정하면 밑에있는 MKMapView 줌 기능을 사용할 수 있습니다. 이 GestureRecognizer'sdelegate에는 gestureRecognizer가 있습니다. 내가지도 위에 핀의 낙하를 허용하는 UILongPressGestureRecognizer을 구현하려고 할 때

// 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) 

내 문제가 발생 다음과 같이 true

이에 shouldRecognizeSimultaneouslyWithGestureRecognizer 세트 viewDidLoad에 설치됩니다. 이것은 참으로 핀이 긴 탭 단일 탭 의지에 투하 할 수 있도록 않습니다

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() 
     } 
    } 
} 

: 이것은 내 액션 메소드입니다

// 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) 

: 나는이 viewDidLoad에 추가 된 다음 사용하려고 해요 콜 아웃을 표시하지만 드래그가 충분히 빨리 시작되지 않은 경우 두 번째 탭을 길게 눌러 드래그하면 두 번째 핀이 드롭됩니다. 이 두 번째 핀은 이전 핀이 있던 공간으로 떨어지고 사용자가 드래그 할 수 있지만 새로운 핀 놓기는 어색하고 잘못된 것입니다.

나는 줄을 사용하려고 해요 :

if let viewAtBottom = viewAtBottomOfHierarchy as? MKPinAnnotationView { 

MKMapView에 탭을 반환하고 다른 핀을 방지하기 위해이 삭제되고 있지만, 수익이 줄에 중단 점 viewAtBottom가의 보여줍니다 비록 호출되지 없구요 MapKit.MKPinAnnotationView을 입력하십시오. 내가 잘못 가고있는 어떤 생각?

+0

해결책이 있습니까? 나는 신속하게 MapKit에 대한 tapGesture를 원한다. 제발 도와주세요 –

+1

주석을 건드린 경우 mapview 대리자 기능이 없습니까? 다른 주석을 삭제해야하는지 또는 현재 주석을 옮길 지 결정하기 위해 긴 누름 기능과 함께 사용하십시오. –

답변

1

정확하게 이해하면 문제에 대한 답변을 얻었을 것 같습니다. 한 핀을 떨어 뜨린 다음 다른 핀을 넣지 않고 화면을 드래그하면 문제가 발생합니까? 이것은 내 코드이며, 나는 비슷한 것을 만들었으며 이것은 나를 위해 작동하는 것 같다. 수입 UIKit 수입 MapKit

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. 
    } 


} 

는 희망이 도움이 수입 CoreLocation이 문제는 최소 길게 누르 기간은 0.5입니다 수 있습니다.