Как настроить выноски пузырь для MKAnnotationView?

голоса
87

Я сейчас работаю с MapKit, и я застрял.

У меня есть мнение пользовательских аннотаций я использую, и я хочу использовать свойство изображения для отображения точки на карте с моим собственным значком. У меня это работает отлично. Но то, что я хотел бы сделать, это переопределить вид выноски по умолчанию (пузырь, который показывает с заголовком / подзаголовком, когда значок аннотации прикоснулась). Я хочу, чтобы иметь возможность контролировать выноски себя: MapKit только обеспечивает доступ к левой и правой вспомогательных взглядов выноски, но никоим образом, чтобы обеспечить пользовательское представление для выноски пузыря, или дать ему нулевой размер, или что-нибудь еще.

Моя идея состояла в том, чтобы переопределить selectAnnotation / deselectAnnotation по моему MKMapViewDelegate, а затем сделать свой собственный вид, сделав вызов на мой взгляд аннотаций. Это работает, но только тогда , когда canShowCalloutбудет установлен YESв моем пользовательском классе просмотра аннотаций. Эти методы не вызываются , если у меня есть этот набор для NO(это то , что я хочу, так что выноски по умолчанию пузырьковые не тянут). Так что у меня нет никакого способа знать , если пользователь коснулся моей точки на карте (выбирается его) или прикоснулся точку , которая не является частью моих взглядов аннотаций (delected его) без выноски по умолчанию просмотр шоу мыльных пузырей вверх по.

Я пытался идти по другому пути и просто обрабатывать все события прикосновения себя на карте, и я не могу показаться, чтобы получить эту работу. Я читал другие сообщения, связанные с ловя сенсорные события в виде карты, но они не совсем то, что я хочу. Есть ли способ, чтобы вырыть в виде карты, чтобы удалить выноски пузыря перед нанесением? Я в недоумении.

Какие-либо предложения? Я пропускаю что-то очевидное?

Задан 14/10/2009 в 13:02
источник пользователем
На других языках...                            


9 ответов

голоса
53

Существует еще проще решение.

Создание пользовательского UIView(для вашей выноски).

Затем создать подкласс MKAnnotationViewи переопределить setSelectedследующим образом :

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    if(selected)
    {
        //Add your custom view to self...
    }
    else
    {
        //Remove your custom view...
    }
}

Boom, работу.

Ответил 05/08/2011 в 12:16
источник пользователем

голоса
40

detailCalloutAccessoryView

В былые времена это была боль, но Apple , решила, просто проверить документы на MKAnnotationView

view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.detailCalloutAccessoryView = UIImageView(image: UIImage(named: "zebra"))

Действительно, это так. Принимает любые UIView.

Ответил 23/07/2012 в 13:44
источник пользователем

голоса
13

Продолжая от @ блестяще простого ответа TappCandy, в, если вы хотите, чтобы оживить ваш пузырь точно так же, как по умолчанию один, я произвел этот метод анимации:

- (void)animateIn
{   
    float myBubbleWidth = 247;
    float myBubbleHeight = 59;

    calloutView.frame = CGRectMake(-myBubbleWidth*0.005+8, -myBubbleHeight*0.01-2, myBubbleWidth*0.01, myBubbleHeight*0.01);
    [self addSubview:calloutView];

    [UIView animateWithDuration:0.12 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^(void) {
        calloutView.frame = CGRectMake(-myBubbleWidth*0.55+8, -myBubbleHeight*1.1-2, myBubbleWidth*1.1, myBubbleHeight*1.1);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.1 animations:^(void) {
            calloutView.frame = CGRectMake(-myBubbleWidth*0.475+8, -myBubbleHeight*0.95-2, myBubbleWidth*0.95, myBubbleHeight*0.95);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.075 animations:^(void) {
                calloutView.frame = CGRectMake(-round(myBubbleWidth/2-8), -myBubbleHeight-2, myBubbleWidth, myBubbleHeight);
            }];
        }];
    }];
}

Это выглядит довольно сложно, но до тех пор , как точка вашего выноски пузырь предназначен для центра дна, вы просто должны быть в состоянии заменить myBubbleWidthи myBubbleHeightс вашим собственным размером для его работы. И помните , чтобы убедиться , что ваши подвиды имеют их autoResizeMaskсвойство установлено в 63 (то есть «все») , чтобы они правильно масштабировать в анимации.

:-Джо

Ответил 24/10/2011 в 13:41
источник пользователем

голоса
8

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

В вашем MKAnnotationViewподклассе, вы можете использовать

- (void)didAddSubview:(UIView *)subview{
    int image = 0;
    int labelcount = 0;
    if ([[[subview class] description] isEqualToString:@"UICalloutView"]) {
        for (UIView *subsubView in subview.subviews) {
            if ([subsubView class] == [UIImageView class]) {
                UIImageView *imageView = ((UIImageView *)subsubView);
                switch (image) {
                    case 0:
                        [imageView setImage:[UIImage imageNamed:@"map_left"]];
                        break;
                    case 1:
                        [imageView setImage:[UIImage imageNamed:@"map_right"]];
                        break;
                    case 3:
                        [imageView setImage:[UIImage imageNamed:@"map_arrow"]];
                        break;
                    default:
                        [imageView setImage:[UIImage imageNamed:@"map_mid"]];
                        break;
                }
                image++;
            }else if ([subsubView class] == [UILabel class]) {
                UILabel *labelView = ((UILabel *)subsubView);
                switch (labelcount) {
                    case 0:
                        labelView.textColor = [UIColor blackColor];
                        break;
                    case 1:
                        labelView.textColor = [UIColor lightGrayColor];
                        break;

                    default:
                        break;
                }
                labelView.shadowOffset = CGSizeMake(0, 0);
                [labelView sizeToFit];
                labelcount++;
            }
        }
    }
}

И если subviewэто UICalloutView, то вы можете ввернуть вокруг с ним, и что внутри него.

Ответил 31/08/2011 в 21:36
источник пользователем

голоса
6

У меня такая же проблема. Существует серьезные сообщения в блоге на эту тему на этом блоге http://spitzkoff.com/craig/?p=81 .

Просто с помощью MKMapViewDelegateне поможет здесь и подклассов MKMapViewи пытается расширить существующую функциональность и не работает для меня.

То , что я в конечном итоге делает это , чтобы создать свой собственный , CustomCalloutViewчто я имею в верхней части моей MKMapView. Вы можете стилизовать эту точку зрения в любом случае вы хотите.

Мой CustomCalloutViewесть метод , подобный этому:


- (void) openForAnnotation: (id)anAnnotation
{
    self.annotation = anAnnotation;
    // remove from view
    [self removeFromSuperview];

    titleLabel.text = self.annotation.title;

    [self updateSubviews];
    [self updateSpeechBubble];

    [self.mapView addSubview: self];
}

Он принимает MKAnnotationобъект и устанавливает свой собственный заголовок, потом он называет два других методов , которые являются весьма некрасиво , которые регулируют ширину и размер содержимого выноски и потом рисовать в речи пузырь вокруг него в правильном положении.

Наконец, вид добавляется как подвид в MAPview. Проблема с этим решением является то, что трудно держать выноски в правильном положении, когда вид карты прокручивается. Я просто скрытие выноски в методе делегата просмотра карты на изменении региона, чтобы решить эту проблему.

Потребовалось некоторое время, чтобы решить все эти проблемы, но теперь выноска почти ведет себя как официальный, но у меня есть это в своем собственном стиле.

Ответил 16/10/2009 в 11:35
источник пользователем

голоса
5

В принципе решить эту проблему, нужно: а) не допускать выноски по умолчанию пузыря на приходить вверх. б) Рисунок из которого аннотаций была нажата.

Я был в состоянии достичь этих путем: а) установка canShowCallout к NO б) подклассов, MKPinAnnotationView и переопределение методов touchesBegan и touchesEnd.

Примечание: Вам нужно обрабатывать события касания для MKAnnotationView и не MKMapView

Ответил 20/11/2009 в 12:22
источник пользователем

голоса
3

Я просто придумать подход, идея здесь

  // Detect the touch point of the AnnotationView ( i mean the red or green pin )
  // Based on that draw a UIView and add it to subview.
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
    CGPoint newPoint = [self.mapView convertCoordinate:selectedCoordinate toPointToView:self.view];
//    NSLog(@"regionWillChangeAnimated newPoint %f,%f",newPoint.x,newPoint.y);
    [testview  setCenter:CGPointMake(newPoint.x+5,newPoint.y-((testview.frame.size.height/2)+35))];
    [testview setHidden:YES];
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    CGPoint newPoint = [self.mapView convertCoordinate:selectedCoordinate toPointToView:self.view];
//    NSLog(@"regionDidChangeAnimated newPoint %f,%f",newPoint.x,newPoint.y);
    [testview  setCenter:CGPointMake(newPoint.x,newPoint.y-((testview.frame.size.height/2)+35))];
    [testview setHidden:NO];
}

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view 
{  
    NSLog(@"Select");
    showCallout = YES;
    CGPoint point = [self.mapView convertPoint:view.frame.origin fromView:view.superview];
    [testview setHidden:NO];
    [testview  setCenter:CGPointMake(point.x+5,point.y-(testview.frame.size.height/2))];
    selectedCoordinate = view.annotation.coordinate;
    [self animateIn];
}

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view 
{
    NSLog(@"deSelect");
    if(!showCallout)
    {
        [testview setHidden:YES];
    }
}

Здесь - TestView является UIViewразмером 320x100 - showCallout является BOOL - [self animateIn];это функция , которая делает вид анимации , как UIAlertView.

Ответил 26/01/2012 в 12:08
источник пользователем

голоса
1

Я толкнул мою вилку превосходной SMCalloutView, который решает проблему с предоставлением пользовательского представления для выноски и позволяя гибкую ширину / высоты довольно безболезненно. Тем не менее некоторые особенности работы, но это довольно функциональный до сих пор:

https://github.com/u10int/calloutview

Ответил 18/10/2012 в 00:04
источник пользователем

голоса
1

Вы можете использовать leftCalloutView, установив annotation.text на @»"

Ниже Вы найдете пример кода:

pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if(pinView == nil){
    pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];       
}
CGSize sizeText = [annotation.title sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:12] constrainedToSize:CGSizeMake(150, CGRectGetHeight(pinView.frame))                                 lineBreakMode:UILineBreakModeTailTruncation];
pinView.canShowCallout = YES;    
UILabel *lblTitolo = [[UILabel alloc] initWithFrame:CGRectMake(2,2,150,sizeText.height)];
lblTitolo.text = [NSString stringWithString:ann.title];
lblTitolo.font = [UIFont fontWithName:@"HelveticaNeue" size:12];
lblTitolo.lineBreakMode = UILineBreakModeTailTruncation;
lblTitolo.numberOfLines = 0;
pinView.leftCalloutAccessoryView = lblTitolo;
[lblTitolo release];
annotation.title = @" ";            
Ответил 14/04/2011 в 10:18
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more