Добавляем subview в MKMapView, что над картой, но ниже представлений аннотаций?
Для приложения, которое я создаю, у меня есть настраиваемый PNG эффекта старой карты, который я бы хотел наложить на представление MKMapView. К сожалению, ни один из способов, которые я пытался сделать это, не был прав:
- Добавить subview в MKMapView (проблема: UIImageView для PNG помещается над контактами Annotation, который выглядит странно
- Сделайте изображение аннотационным представлением и поместите его ниже других (проблема: в прокрутке мне нужно переместить изображение с аннотацией, а на некоторое время вместо обычного эффекта используется только обычная карта).
То, что я в основном хочу выполнить, - это иметь представление под надзором, которое накладывается над maptiles, но ниже представлений аннотаций, и оно будет устойчивым, пока пользователь прокручивается - любые мысли?
Ответы
Ответ 1
Обратите внимание, что вся иерархия subviews MKMapView
, аннотации, поведение и т.д. происходит во внутреннем частном MKMapViewInternal, что меняет что-либо (в некотором смысле, я предлагаю или другое) в этой структуре может привести к тому, что ваше приложение будет отклонено из Appstore.
У меня нет полного решения, просто идея. Моя идея состоит в том, чтобы сделать оверлейное представление с тем же видом наблюдения, что и аннотационные представления, и гарантировать, что аннотации будут помещены поверх нашего наложения. В MKMapViewDelegate мы реализуем:
- (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views{
if (views.count > 0){
UIView* tView = [views objectAtIndex:0];
UIView* parView = [tView superview];
UIView* overlay = [tView viewWithTag:2000];
if (overlay == nil){
overlay = [[UIImageView alloc] initWithImage:[UIImage imageNamed:MY_IMAGE_NAME]];
overlay.frame = parView.frame; //frame equals to (0,0,16384,16384)
overlay.tag = 2000;
overlay.alpha = 0.7;
[parView addSubview:overlay];
[overlay release];
}
for (UIView* view in views)
[parView bringSubviewToFront:view];
}
}
Этот код делает половину того, что вы хотите - вы получаете представление, размещенное между фрагментами карт и аннотациями. Оставшаяся задача состоит в том, чтобы изменить пользовательский режим оверлея в соответствии с прокруткой/масштабированием карты (я отправлю, если найду способ).
Ответ 2
В конце концов я сделал нечто похожее и по-другому. Я хотел убрать изображение карты, добавив белый оверлей, но я не хотел исчезать аннотации. Я добавил оверлей к карте (на самом деле мне пришлось добавить два, поскольку мне не понравилось, что я пытаюсь добавить наложение для всего земного шара).
CLLocationCoordinate2D pt1, pt2, pt3, pt4;
pt1 = CLLocationCoordinate2DMake(85, 0);
pt2 = CLLocationCoordinate2DMake(85, 180);
pt3 = CLLocationCoordinate2DMake(-85, 180);
pt4 = CLLocationCoordinate2DMake(-85, 0);
CLLocationCoordinate2D coords[] = {pt1, pt2, pt3, pt4};
MKPolygon *p = [MKPolygon polygonWithCoordinates:coords count:4];
[self.mapView addOverlay:p];
pt1 = CLLocationCoordinate2DMake(85, 0);
pt2 = CLLocationCoordinate2DMake(85, -180);
pt3 = CLLocationCoordinate2DMake(-85, -180);
pt4 = CLLocationCoordinate2DMake(-85, 0);
CLLocationCoordinate2D coords2[] = {pt1, pt2, pt3, pt4};
MKPolygon *p2 = [MKPolygon polygonWithCoordinates:coords2 count:4];
[self.mapView addOverlay:p2];
Затем вам нужно добавить делегат карты, чтобы нарисовать их:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
if ([overlay isKindOfClass:MKPolygon.class]) {
MKPolygonRenderer *polygonView = [[MKPolygonRenderer alloc] initWithOverlay:overlay];
polygonView.fillColor = [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:0.4];
return polygonView;
}
return nil;
}
Ответ 3
Это довольно старый, но, возможно, все еще актуальный для некоторых из вас.
Я хотел сделать карту более темной, но не аннотациями.
То, что я сделал, было очень простым, и я еще не знаю, есть ли у него резервные копии...
Я положил UIView
с черно-прозрачным фоном над MKMapView
, а затем добавил следующий код:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray<MKAnnotationView *> *)views
{
for (MKAnnotationView *view in views) {
view.center = [self.mapView convertCoordinate:view.annotation.coordinate toPointToView:self.viewDark];
[self.viewDark addSubview:view];
}
}
Надеюсь, что это поможет.. и, конечно же, если вы найдете какие-либо проблемы с этим решением, пожалуйста, дайте мне знать:)
Изменить # 1:
Забыл упомянуть, что self.viewDark
должен иметь userInteraction
отключен.
Изменить # 2:
Еще одна вещь, которая помогла мне, - установить self.viewDark
autoresizesSubviews
на NO
.