web-dev-qa-db-ja.com

MapKitアノテーションが消える

CLLocationCoordinate2Dタイプの配列に追加する、緯度の配列と経度の別の配列があります。次に、新しい配列を使用して、マップ上の複数のポイントに注釈を付けます。一部、またはほとんど、あるいはすべての注釈がマップに表示されていますが、ズームイン(はい、ズームイン)すると、一部の注釈が消えてから戻ってくるか、表示されません。それらをすべて表示し続ける方法についてのアイデアはありますか?これは、ズームインではなくズームアウト中に予想される動作です。

これが私が上で説明したものに使用しているコードです。

import UIKit
import MapKit
import CoreLocation

class MultiMapVC: UIViewController, CLLocationManagerDelegate {

@IBOutlet weak var multiEventMap: MKMapView!

var latDouble = Double()
var longDouble = Double()
let manager = CLLocationManager()
var receivedArrayOfLats = [Double]()
var receivedArrayOfLongs = [Double]()
var locations = [CLLocationCoordinate2D]()


func locationManager(_ manager: CLLocationManager, didUpdateLocations uLocation: [CLLocation]) {
    let userLocation = uLocation[0]
    let span:MKCoordinateSpan = MKCoordinateSpanMake(0.3, 0.3)
    let usersLocation = userLocation.coordinate
    let region:MKCoordinateRegion = MKCoordinateRegionMake(usersLocation, span)
    multiEventMap.setRegion(region, animated: true)
    manager.distanceFilter = 1000
    self.multiEventMap.showsUserLocation = true
}

func multiPoint() {

    var coordinateArray: [CLLocationCoordinate2D] = []
    print ("Received Longitude Count = \(receivedArrayOfLongs.count)")
    print ("Received Latitude Count = \(receivedArrayOfLats.count)")
    if receivedArrayOfLats.count == receivedArrayOfLongs.count {
        for i in 0 ..< receivedArrayOfLats.count {
            let eventLocation = CLLocationCoordinate2DMake(receivedArrayOfLats[i], receivedArrayOfLongs[i])
            coordinateArray.append(eventLocation)
            print (coordinateArray.count)
        }
    }

    for events in coordinateArray {
        let annotation = MKPointAnnotation()
        annotation.coordinate = CLLocationCoordinate2D(latitude: events.latitude, longitude: events.longitude)
        multiEventMap.addAnnotation(annotation)
        }
}


override func viewDidLoad() {
    super.viewDidLoad()
    manager.delegate = self
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.requestWhenInUseAuthorization()
    manager.startUpdatingLocation()
    multiPoint()
        }


override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    multiEventMap.removeFromSuperview()
    self.multiEventMap = nil

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

12
jvan

NiltiakSivadのソリューションは機能しますが、古いiOS10の外観に戻ります。 iOS11用の新しいiOS11バルーンマーカーを保持し、古いiOSバージョンに対してのみ古いピンルックを使用する場合は、次のようにデリゲートメソッドを実装できます。

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    let reuseIdentifier = "annotationView"
    var view = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
    if #available(iOS 11.0, *) {
        if view == nil {
            view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
        }
        view?.displayPriority = .required
    } else {
        if view == nil {
            view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
        }
    }
    view?.annotation = annotation
    view?.canShowCallout = true
    return view
}
11
Leszek Szary

同様の問題が発生していました。私の推測では、iOS11がピンの衝突を検出する方法と関係があると思います。カスタム注釈ビューを実装するか、iOS 10ピンを使用するように戻すと、問題が修正されました。

たとえば、以下を実装すると、コードが修正されます。

class MultiMapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
   override func viewDidLoad() {
       super.viewDidLoad()
       mapView.delegate = self    
    }

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
       guard let annotation = annotation as? MKPointAnnotation else { return nil }

       let identifier = "pin-marker"
       var view: MKAnnotationView

       if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView {
           dequeuedView.annotation = annotation
           view = dequeuedView
       } else {
           view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
       }
       return view
   }
}

これが機能しない場合は、さまざまなズームレベルでピンを非表示/表示するタイミングを決定するのに役立つため、調べる価値のあるdisplayPriorityプロパティがあります。詳細については https://developer.Apple.com/documentation/mapkit/mkannotationview/2867298-displaypriority

お役に立てれば。

5
NiltiakSivad

LeszekSzaryから受け入れられた答えは正しいです。

しかし、いくつかの細かい点があります。 MKMarkerAnnotationViewsは、たとえ

view.displayPriority = .required

が設定されています。

あなたが見ているのは、異なるルールの組み合わせです。

  1. MKAnnotationViewsは、マップの上から下にレンダリングされます。 (北がどこにあるかは関係ありません)。
  2. MapKitが重複するMKAnnotationViewsを描画することを決定した場合、下部に近いMKAnnotationViewが上部に描画されます(後で描画されるため)
  3. MKAnnotationViewsだけでなく、MKMArkerAnnotationViewsの下に表示されるタイトルにもスペースが必要です。これらのタイトルのレンダリングは、markerView.titleVisibilityの影響を受けます。 markerView.titleVisibilityが(デフォルトの.visibleではなく).adaptiveに設定されている場合、このタイトルは、後のMarkerAnnotationViewdisplayPriority = .requiredがある場合でも、後でレンダリングされるMarkerAnnotationViewよりも強力です。一番下に近いMarkerAnnotationViewはレンダリングされません。
  4. これは、上部に近いMarkerAnnotationViewdisplayPriorityが低い場合でも発生します。したがって、MarkerAnnotationView.titleVisibility = .visibleが低いdisplayPriorityを使用すると、MarkerAnnotationViewを下部に近づけてdisplayPriority = .requiredを非表示にすることができます。

私はこの振る舞いの文書を知りません。これは、iOS12での私の実験の結果です。私の説明は単純化されています。

3
Gerd Castan

MKMarkAnnotationViewが最初に割り当てられたときだけ、annotationView.displayPriority = .requiredを設定していました。通常はこれですべてですが、セルを再利用するたびに設定すると、問題が解決しました。

2
Josh Bernfeld

Xcode10とiOS12 +を展開ターゲットとして同様の問題が発生していました。 Appleスタッフ( https://forums.developer.Apple.com/thread/92839 ))からの投稿では、の.isHiddenプロパティを切り替えることを推奨しています。デキューされたマーカー。これにより状況は改善されましたが、問題は完全には解決されていません。

result?.isHidden = true
result?.isHidden = false
return result
0
Hal Mueller