Z-упорядочение MKAnnotationViews
-
16-09-2019 - |
Вопрос
Меня очень расстраивают ограничения MKMapKit.Моя текущая проблема связана с z-упорядочением представлений аннотаций, особенно в том, что касается касаний.Если вы принимаете z-порядок по умолчанию, набор карт дает вам:
- Порядок кажется случайным.Z-порядок не связан с порядком добавления аннотаций.
- Если одна аннотация оказывается поверх другой, прикосновение к верхней аннотации обычно вызывает выноску нижней аннотации.Кажется, что обнаружение попаданий даже не учитывает порядок отрисовки.Что с этим случилось?
Я попытался решить № 1, используя что-то похожее на следующий код, найденный в Интернете (который был разработан, чтобы дать некоторый контроль над z-порядком)
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views { for (MKAnnotationView * annView in views) { TopBottomAnnotation * ann = (TopBottomAnnotation *) [annView annotation]; if ([ann top]) { [[annView superview] bringSubviewToFront:annView]; } else { [[annView superview] sendSubviewToBack:annView]; } } }
Просмотр представлений аннотаций, переданных в MapView:didAddAnnotationViews:и изменение их z-порядка, похоже, исправляет №1.Проблема в том, что теперь виды выносок больше не всегда располагаются поверх представлений аннотаций.MapKit, кажется, очень запутался в слоях (выноски должны быть нарисованы на слое над всеми видами аннотаций).Я даже могу понять, почему это запутывается, поскольку все получаемые вами MKAnnotationViews имеют одно и то же суперпредставление (частный класс MKOverlayView).Вы могли бы подумать, что любой разумный дизайн будет содержать выноски об этом наложенном представлении.
Кто-нибудь успешно решил №1 или №2?
Решение
Если у вас есть собственный annotationView (похоже, что он у вас уже есть), вы можете попробовать добавить это:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.superview bringSubviewToFront:self];
[super touchesBegan:touches withEvent:event];
}
Побочным эффектом является то, что каждый раз, когда к маркеру прикасаются, он также перемещается в начало z-порядка, что на самом деле разумно, поскольку именно на этом фокусируется пользователь.
Другие советы
Рамин, это идеально подходит для того, что я пытаюсь сделать.Однако у меня не было определенного пользовательского представления аннотаций.Я решил эту проблему, используя категорию, и все сработало идеально!
Вот заголовок:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface MKPinAnnotationView (ZIndexFix)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
@end
И реализация:
#import "AEBMapViewCategory.h"
@implementation MKPinAnnotationView (ZIndexFix)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.superview bringSubviewToFront:self];
[super touchesBegan:touches withEvent:event];
}
@end
Попробуйте другое решение, настройте zPosition слоя представления аннотаций (annotationView.layer.zPosition) в:
(void)mapView:(MKMapView *)mapView DidAddAnnotationViews:(NSArray *)views;