2016-12-20 2 views
0

MKPinAnnotationView 개체를 보여주는 MKMapView이 있습니다.
주석보기를 끌고 싶지만 선택할 수 있기를 원합니다.드래그하거나 선택할 수있는 포인트 주석보기를 사용할 수 있습니까?

문제 : 나는 주석보기로을 터치하면

내가 대리자 기능

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {…} 

이 기능을 구현

즉시 라고합니다. 경고를 표시하므로 주석 뷰가 드래그되지 않습니다.

대리자 기능을 구현하지 않으면 주석보기를 예상대로 끌 수 있습니다.

다음이 가능해야한다고 생각합니다.
- 주석보기로 터치합니다.
- 드래그 할 때 특수 효과보기를 이동하십시오.
- 아니요, 즉 주석보기에서을 터치하면 선택합니다.

어떻게하면됩니까?

편집 :

내 핀 주석보기 콜 아웃이 없습니다. 대신, 사용자가 추가 작업을 선택할 수 있도록 UIAlertController을 표시합니다. 그렇다면 mapView이 흐리게 표시되어 액세스 할 수 없습니다.

I가 구현하려는 동작 :

내가 (손가락 아래) 핀 주석보기를 터치하면 아무 일이 없어야합니다.

손가락을 움직이면 (여전히 아래로) 핀 주석보기를 드래그해야합니다. 그런 다음 손가락을 들어 올리면 핀 주석보기가 이 아닌이 선택됩니다.

그러나 손가락을 조작하지 않고 단순히 들어 올리면 핀 주석보기 으로 선택됩니다 (경고보기가 표시되어야 함).

이 상황이 명확 해지기를 바랍니다.

+0

해명의 몇 가지, 당신은 주석보기가 선택 될 때 선이 표시되고 있음을 의미합니까? 또한, "터치 업"이라고 할 때 손가락을 들어 올릴 때 (터치 다운하려면 반대)를 의미합니까? –

+0

주석을 선택하고 두 개의 다른 동작으로 드래그하는 것을 볼 수 있습니다. 표준 핀 주석보기를 사용하여 설명 선을 표시 할 핀을 선택한 다음 핀을 다시 선택하여 드래그를 시작합니다. 사용자가 핀을 드래그하지 않으려면 설명 선을보기 위해 핀을 선택할 수 있습니다. –

+0

죄송합니다. 내 질문에 명확하지 않았습니다. 나는 그것을 새롭게 할 것이다. –

답변

1

가능한 해결 방법 중 하나는 직접 드래그를 처리하고 길게 누르는 제스처를 사용하여 원하는 작업 (예 : 경고 표시시기)을 관리하는 것입니다.

이 솔루션은 롭의 자세한 답변을 here 중심으로 구축 및 질문 (즉 wasMoved 인스턴스 속성)의 세부 사항을 처리하기 위해 몇 가지 추가 로직을 추가한다.

private var startLocation = CGPoint(x: 0.0, y: 0.0) 
private var wasMoved = false 

func handleLongPress(_ sender: UILongPressGestureRecognizer) { 
    let location = sender.location(in: mapView) 

    switch sender.state { 
    case .began: 
     startLocation = location 
    case .changed: 
     wasMoved = true 
     sender.view?.transform = CGAffineTransform(translationX: location.x - startLocation.x, y: location.y - startLocation.y) 
    case .ended, .cancelled: 
     if wasMoved { 
      let annotationView = sender.view as! MKAnnotationView 
      let annotation = annotationView.annotation as! MKPointAnnotation 

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

      annotationView.transform = CGAffineTransform.identity 
      annotation.coordinate = mapView.convert(updatedLocation, toCoordinateFrom: mapView) 
     } else { 
      let alert = UIAlertController(title: "Alert", message: "Here is my alert!", preferredStyle: .alert) 

      let ok = UIAlertAction(title: "OK", style: .default, handler: nil) 
      alert.addAction(ok) 

      present(alert, animated: true, completion: nil) 
     } 
     wasMoved = false 
    default: 
     break 
    } 
} 

그리고 당신의 mapView(_:viewFor:) 위임 방법과 같을 것이다 : "경고 표시"로,

extension ViewController: MKMapViewDelegate { 
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 
     guard let reusablePin = mapView.dequeueReusableAnnotationView(withIdentifier: "Pin") as? MKPinAnnotationView else { 
      let pin = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "Pin") 

      // Add the long press gesture recognizer to the annotation view 
      let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:))) 
      longPress.minimumPressDuration = 0 
      pin.addGestureRecognizer(longPress) 

      return pin 
     } 

     reusablePin.annotation = annotation 
     return reusablePin 
    } 
} 
+0

자세한 답변을 주셔서 감사합니다 (+1). Xmas 때문에 내 앱을 테스트하는 데 며칠이 걸립니다. 지연되어 죄송합니다. Reiner –

+0

@ReinhardManner 걱정할 필요가 없습니다. 대답은 일부 리팩터링을 사용할 수 있지만 내 테스트 (Xcode 8.2, Swift 3 및 iOS 10)를 기반으로 작동해야합니다. –

관련 문제