MKMapView не снимает кластеризацию, когда контакты близки - PullRequest
0 голосов
/ 21 октября 2018

У меня есть mapView с 4 контактами, как показано ниже.Когда я уменьшил масштаб, все 4 отлично сгруппировались.

Проблема возникает, когда я увеличиваю изображение настолько, насколько могу.2 из 4 штырьков извлекаются из кластера и помещаются сами по себе ... но остальные 2 по-прежнему кластеризованы, и я не могу увеличить их, чтобы увидеть их!

Если я использую GoogleMaps SDK, этопозволяет мне увеличить масштаб достаточно, чтобы увидеть ВСЕ 4 штырька ... но с MKMapView я не могу увеличить достаточно.Любые идеи, как я могу заставить это остановить кластеризацию, когда я полностью увеличен?

Код репликации:

//
//  ViewController.swift
//  MapTest
//
//  Created by Brandon on 2018-10-21.
//  Copyright © 2018 XIO. All rights reserved.
//

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    private let mapView = { () -> MKMapView in
        let mapView = MKMapView()
        let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)
        let location = CLLocationCoordinate2D(latitude: 43.6529, longitude: -79.3849)
        let region = MKCoordinateRegion(center: location, span: span)
        mapView.setRegion(region, animated: true)
        return mapView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        mapView.delegate = self
        mapView.translatesAutoresizingMaskIntoConstraints = false

        mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
        mapView.register(CustomClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)

        view.addSubview(mapView)
        NSLayoutConstraint.activate([
            mapView.leftAnchor.constraint(equalTo: view.leftAnchor),
            mapView.rightAnchor.constraint(equalTo: view.rightAnchor),
            mapView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            mapView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])

        let annotation1 = CustomAnnotation(coordinate: CLLocationCoordinate2D(latitude: 43.6529, longitude: -79.3849))
        let annotation2 = CustomAnnotation(coordinate: CLLocationCoordinate2D(latitude: 43.65291, longitude: -79.3849))
        let annotation3 = CustomAnnotation(coordinate: CLLocationCoordinate2D(latitude: 43.6528, longitude: -79.3849))
        let annotation4 = CustomAnnotation(coordinate: CLLocationCoordinate2D(latitude: 43.6527, longitude: -79.3848))

        mapView.addAnnotations([annotation1, annotation2, annotation3, annotation4])
    }

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        if let annotation = annotation as? CustomAnnotation {
            var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation) as? CustomAnnotationView

            if annotationView == nil {
                annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
            }

            annotationView?.clusteringIdentifier = "ClusteringID"

            return annotationView
        }

        if let annotation = annotation as? CustomClusterAnnotation {
            var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier, for: annotation) as? CustomClusterAnnotationView

            if annotationView == nil {
                annotationView = CustomClusterAnnotationView(annotation: annotation, reuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
            }

            annotationView?.onPinTapped = { [weak self] pin in
                if let annotation = pin.annotation as? CustomClusterAnnotation, let mapView = self?.mapView {
                    mapView.showAnnotations(annotation.memberAnnotations, animated: true)

//                    let point = MKMapPoint(annotation.coordinate)
//                    var rect = mapView.visibleMapRect
//                    rect.size.width = 10.0
//                    rect.size.height = 10.0
//
//                    rect.origin.x = point.x - rect.size.width * 0.5
//                    rect.origin.y = point.y - rect.size.height * 0.5
//                    mapView.setVisibleMapRect(rect, animated: true)
                }
            }

            return annotationView
        }

        return nil
    }

    func mapView(_ mapView: MKMapView, clusterAnnotationForMemberAnnotations memberAnnotations: [MKAnnotation]) -> MKClusterAnnotation {
        return CustomClusterAnnotation(memberAnnotations: memberAnnotations)
    }
}


//Just some custom annotation views..

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

    init(coordinate: CLLocationCoordinate2D) {
        self.coordinate = coordinate
    }
}

class CustomClusterAnnotation: MKClusterAnnotation {
    override init(memberAnnotations: [MKAnnotation]) {
        super.init(memberAnnotations: memberAnnotations)

        title = "\(memberAnnotations.count)"
        subtitle = nil
    }
}

class CustomAnnotationView: MKAnnotationView {
    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

        self.isUserInteractionEnabled = true
        //image = #imageLiteral(resourceName: "map-annotation")

        if image == nil {
            let displayView = UIView()
            displayView.translatesAutoresizingMaskIntoConstraints = false
            displayView.backgroundColor = .red
            displayView.layer.cornerRadius = 5.0

            addSubview(displayView)
            NSLayoutConstraint.activate([
                displayView.widthAnchor.constraint(equalTo: displayView.heightAnchor),
                displayView.centerXAnchor.constraint(equalTo: centerXAnchor),
                displayView.centerYAnchor.constraint(equalTo: centerYAnchor),
                displayView.heightAnchor.constraint(equalToConstant: 10.0)
            ])
        }
    }

    @available(*, unavailable)
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class CustomClusterAnnotationView: MKAnnotationView {

    var onPinTapped: ((CustomClusterAnnotationView) -> Void)?

    private let titleLabel = { () -> UILabel in
        let label = UILabel()
        label.textColor = .white
        label.font = UIFont.systemFont(ofSize: 25.0, weight: .bold)
        label.numberOfLines = 0
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    private let backgroundView = { () -> UIView in
        let view = UIView()
        view.layer.masksToBounds = true
        view.backgroundColor = .blue
        view.isUserInteractionEnabled = true
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

        self.isUserInteractionEnabled = true

        addSubview(backgroundView)
        backgroundView.addSubview(titleLabel)

        NSLayoutConstraint.activate([
            titleLabel.leftAnchor.constraint(equalTo: backgroundView.leftAnchor, constant: 5.0),
            titleLabel.rightAnchor.constraint(equalTo: backgroundView.rightAnchor, constant: -5.0),
            titleLabel.topAnchor.constraint(equalTo: backgroundView.topAnchor, constant: 5.0),
            titleLabel.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor, constant: -5.0)
        ])

        NSLayoutConstraint.activate([
            backgroundView.widthAnchor.constraint(equalTo: backgroundView.heightAnchor),
            backgroundView.centerXAnchor.constraint(equalTo: centerXAnchor),
            backgroundView.centerYAnchor.constraint(equalTo: centerYAnchor)
        ])

        let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(onPinTapped(_:)))
        gestureRecognizer.numberOfTouchesRequired = 1
        gestureRecognizer.numberOfTapsRequired = 1
        backgroundView.addGestureRecognizer(gestureRecognizer)
    }

    @available(*, unavailable)
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override var annotation: MKAnnotation? {
        willSet {
            guard let annotation = newValue as? MKClusterAnnotation else { return }
            titleLabel.text = "\(annotation.memberAnnotations.count)"
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        backgroundView.layer.cornerRadius = backgroundView.bounds.height / 2.0
        bounds = backgroundView.bounds
    }

    override func prepareForReuse() {
        super.prepareForReuse()

        bounds = backgroundView.bounds
    }

    @objc
    private func onPinTapped(_ gestureRecognizer: UITapGestureRecognizer) {
        onPinTapped?(self)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...