Reputation: 468
When creating a custom MKAnnotationView
, called GroupUserAnnotationView
, it is only registering the tapping on the bottom part of the annotation, but not the top. I've tried to add a UITapGestureRecognizer
to the annotation view, but it did not work.
Creating the annotation view:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !annotation.isKind(of: MKUserLocation.self) else {
return nil
}
var annotationView: MKAnnotationView!
var annotationIdentifier: String!
if annotation.isKind(of: GroupUserAnnotation.self) {
annotationIdentifier = "groupUser"
annotationView = GroupUserAnnotationView(annotation: annotation as! GroupUserAnnotation, reuseIdentifier: annotationIdentifier)
annotationView.frame = (annotationView as! GroupUserAnnotationView).containerView.frame
} else {
annotationIdentifier = "marker"
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
}
return annotationView
}
The GroupUserAnnotationView
:
class GroupUserAnnotation: MKPointAnnotation {
var email: String!
var image: UIImage!
}
class GroupUserAnnotationView: MKAnnotationView {
public lazy var containerView: UIView = {
let view = UIView(frame: CGRect(x: -40, y: -70, width: 70, height: 70))
view.backgroundColor = .accentColor
view.layer.cornerRadius = view.frame.width / 2
view.isUserInteractionEnabled = true
return view
}()
public lazy var imageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = (annotation as! GroupUserAnnotation).image!
imageView.clipsToBounds = true
imageView.isUserInteractionEnabled = true
return imageView
}()
public lazy var bottomCornerView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .accentColor
view.layer.cornerRadius = 4.0
view.isUserInteractionEnabled = true
return view
}()
// MARK: Initialization
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation as! GroupUserAnnotation, reuseIdentifier: reuseIdentifier)
setupView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func setupView() {
subviews.forEach({ $0.removeFromSuperview() })
containerView.addSubview(bottomCornerView)
bottomCornerView.topAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -20.0).isActive = true
bottomCornerView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor, constant: 2).isActive = true
bottomCornerView.widthAnchor.constraint(equalToConstant: 24).isActive = true
bottomCornerView.heightAnchor.constraint(equalToConstant: 24).isActive = true
let angle = (39.0 * CGFloat.pi) / 180
let transform = CGAffineTransform(rotationAngle: angle)
bottomCornerView.transform = transform
addSubview(containerView)
containerView.addSubview(imageView)
imageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 2.0).isActive = true
imageView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 2.0).isActive = true
imageView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -2.0).isActive = true
imageView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -2.0).isActive = true
imageView.layer.cornerRadius = (containerView.frame.size.width - 1) / 2
}
And again, only the bottom part of the annotation is actually registering (which means that I have properly implemented the mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)
delegate function.
Any help would be appreciated.
Thanks!
Upvotes: 0
Views: 52
Reputation: 6849
It is even worse: the tap is recognised by the map behind your UIView and causes unintended actions.
The workaround that works for me is using enabled UIControl
s instead of UIView
s.
This can be a UIButton
s that you use directly as buttons, or an invisible enabled large button in the background and UIView
s on top.
The big invisible UIButton
in the background has the task of preventing taps going through to the map.
Use smaller visible buttons on top for normal user interaction, if needed.
Upvotes: 1