Подтвердить что ты не робот

Настроить MKnnotation Callout View?

У меня есть MKPointAnnotation:

let ann = MKPointAnnotation()
self.ann.coordinate = annLoc
self.ann.title = "Customize me"
self.ann.subtitle = "???"
self.mapView.addAnnotation(ann)

Он выглядит следующим образом:

enter image description here

Как настроить это представление выноски для создания собственного представления вместо предопределенного?

4b9b3361

Ответ 1

Прежде всего следует отметить, что простейшие изменения выноски включаются путем простой настройки свойств предоставленной системы выноски, но настройки правого и левого аксессуаров (через rightCalloutAccessoryView и leftCalloutAccessoryView). Вы можете сделать эту конфигурацию в viewForAnnotation.

В iOS 9 теперь у нас есть доступ к detailCalloutAccessoryView, который заменяет субтитры выноски потенциально визуально богатым представлением, сохраняя при этом автоматическое воспроизведение пузырька выноска (с помощью автоматической компоновки это упрощает).

Например, вот выноска, в котором используется MKSnapshotter, чтобы предоставить изображение для просмотра изображения в аксессуаре дополнительной выноски, как показано в видео WWDC 2015 Что нового в MapKit:

введите описание изображения здесь

Вы можете добиться этого с помощью чего-то вроде:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    if annotation is MKUserLocation {
        return nil
    }

    let identifier = "MyCustomAnnotation"

    var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
    if annotationView == nil {
        annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        annotationView?.canShowCallout = true
    } else {
        annotationView!.annotation = annotation
    }

    configureDetailView(annotationView!)

    return annotationView
}

func configureDetailView(annotationView: MKAnnotationView) {
    let width = 300
    let height = 200

    let snapshotView = UIView()
    let views = ["snapshotView": snapshotView]
    snapshotView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[snapshotView(300)]", options: [], metrics: nil, views: views))
    snapshotView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[snapshotView(200)]", options: [], metrics: nil, views: views))

    let options = MKMapSnapshotOptions()
    options.size = CGSize(width: width, height: height)
    options.mapType = .SatelliteFlyover
    options.camera = MKMapCamera(lookingAtCenterCoordinate: annotationView.annotation!.coordinate, fromDistance: 250, pitch: 65, heading: 0)

    let snapshotter = MKMapSnapshotter(options: options)
    snapshotter.startWithCompletionHandler { snapshot, error in
        if snapshot != nil {
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
            imageView.image = snapshot!.image
            snapshotView.addSubview(imageView)
        }
    }

    annotationView.detailCalloutAccessoryView = snapshotView
}

Если вы ищете более радикальную модификацию выноски или вам нужно поддерживать версии iOS до 9, она требует больше работы. Процесс влечет за собой: (а) отключение выноски по умолчанию; и (б) добавление собственного представления, когда пользователь нажимает на существующий вид аннотации (т.е. визуальный вывод на карте).

Затем возникает сложность дизайна выноски, где вы должны нарисовать все, что хотите видеть. Например. если вы хотите нарисовать пузырь, чтобы вы почувствовать прикосновение вызова, вы должны сделать это сами. Но с некоторым знакомством с тем, как рисовать фигуры, изображения, текст и т.д., Вы должны иметь возможность отображать выноску, которая достигает желаемого UX:

пользовательская выноска

Просто добавьте представление в качестве подсмотра самого представления аннотации и соответствующим образом скорректируйте его ограничения:

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    let calloutView = ...
    calloutView.translatesAutoresizingMaskIntoConstraints = false
    calloutView.backgroundColor = UIColor.lightGrayColor()
    view.addSubview(calloutView)

    NSLayoutConstraint.activateConstraints([
        calloutView.bottomAnchor.constraintEqualToAnchor(view.topAnchor, constant: 0),
        calloutView.widthAnchor.constraintEqualToConstant(60),
        calloutView.heightAnchor.constraintEqualToConstant(30),
        calloutView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor, constant: view.calloutOffset.x)
    ])
}

См. https://github.com/robertmryan/CustomMapViewAnnotationCalloutSwift пример создания собственного вида выноски. Это добавляет только две метки, но это иллюстрирует тот факт, что вы можете нарисовать пузырь любой желаемой фигуры, использовать ограничения, чтобы определять размер выноски и т.д.

Ответ 2

Создать Cocoa файл с помощью classtype MKAnnotationView

Файл CustomeAnnotationView.h

@interface CustomeAnnotationView : MKAnnotationView
@property (strong, nonatomic) UIButton *buttonCustomeCallOut;
- (void)setSelected:(BOOL)selected animated:(BOOL)animated;
@end

Файл CustomeAnnotationView.m

@implementation CustomeAnnotationView

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}


- (void)setSelected:(BOOL)selected animated:(BOOL)animated{

    [super setSelected:selected animated:animated];

    if(selected)
    {



            self.buttonCustomeCallOut = [UIButton buttonWithType:UIButtonTypeCustom];//iconShare//iconShareBlue

            [self.buttonCustomeCallOut addTarget:self action:@selector(buttonHandlerCallOut:) forControlEvents:UIControlEventTouchDown];
        [self.buttonCustomeCallOut setBackgroundColor:[UIColor blueColor]];

            [self.buttonCustomeCallOut setFrame:CGRectMake(-40,-80, 100, 100)];



            [self addSubview:self.buttonCustomeCallOut];

        [self.buttonCustomeCallOut setUserInteractionEnabled:YES];
    }
    else
    {
        //Remove your custom view...
        [self.buttonCustomeCallOut setUserInteractionEnabled:NO];
        [self.buttonCustomeCallOut removeFromSuperview];

        self.buttonCustomeCallOut=nil;
    }
}
-(void)buttonHandlerCallOut:(UIButton*)sender{
    NSLog(@"Annotation Clicked");
}

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
    UIView* v = [super hitTest:point withEvent:event];
    if (v != nil)
    {
        [self.superview bringSubviewToFront:self];
    }
    return v;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
{
    CGRect rec = self.bounds;
    BOOL isIn = CGRectContainsPoint(rec, point);
    if(!isIn)
    {
        for (UIView *v in self.subviews)
        {
            isIn = CGRectContainsPoint(v.frame, point);
            if(isIn)
                break;
        }
    }
    return isIn;
}
@end

поместите этот код, где вы хотите создать вызов custome

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    static NSString *identifier = @"CustAnnotation";

        CustomeAnnotationView *annotationView = (CustomeAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) {
            annotationView = [[CustomeAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        }

        annotationView.enabled = YES;
        annotationView.canShowCallout = NO;
        annotationView.centerOffset = CGPointMake(0,-10);//-18

        return annotationView;
}