Jak dostosować objaśnienia dla MKAnnotationView bańka?

głosy
87

Obecnie pracuję z mapkit i jestem zakleszczony.

Mam niestandardowego widoku adnotacji używam i chcę użyć właściwości obrazu, aby wyświetlić punkt na mapie z własnej ikony. Mam ten działa poprawnie. Ale co chciałbym również zrobić to przesłonić widok domyślny objaśnienia (bańkę, która pokazuje się z tytułowym / napisów, gdy ikona adnotacji dotknięciu). Chcę być w stanie kontrolować objaśnienie się: the mapkit zapewnia dostęp do lewego i prawego dodatkowych objaśnień widoków, ale nie sposób, aby zapewnić niestandardowy widok dla bańki objaśnienia lub nadać mu zerowej wielkości, ani nic innego tylko.

Mój pomysł był aby zastąpić selectAnnotation / deselectAnnotation w moim MKMapViewDelegate, a następnie narysować własną niestandardową widok poprzez wykonanie połączenia do mojego widoku niestandardowego adnotacji. To działa, ale tylko wtedy, gdy canShowCalloutjest ustawiony YESw moim niestandardowego widoku opisu klasy. Metody te nie są nazywane jeśli mam ten zestaw do NO(co jest to, co chcę, tak że bańka domyślny objaśnienie nie jest zasysane). Więc nie mam możliwości dowiedzenia się, czy użytkownik dotknął mojego punktu na mapie (wybrano go) albo dotknął punkt, który nie jest częścią mojego widokach adnotacji (delected go) bez konieczności wywołania domyślnego widoku bańka pokazać.

Próbowałem zejście inną drogę i po prostu obsługi wszystkich zdarzeń dotykowych się na mapie, a ja nie wydaje się uzyskać tej pracy. Czytałem inne posty związane z przechwytywanie zdarzeń dotykowych w widoku mapy, ale nie są one dokładnie to, co chcę. Czy istnieje sposób, aby kopać w widoku mapy, aby usunąć pęcherzyk objaśnienia przed rysunek? Jestem w rozterce.

Jakieś sugestie? Jestem brakuje czegoś oczywiste?

Utwórz 14/10/2009 o 13:02
źródło użytkownik
W innych językach...                            


9 odpowiedzi

głosy
53

Jest jeszcze prostsze rozwiązanie.

Utworzyć niestandardowy UIView(dla objaśnienia).

Następnie należy utworzyć podklasę MKAnnotationViewi zastąpić setSelectedw następujący sposób:

- (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, wykonane zadanie.

Odpowiedział 05/08/2011 o 12:16
źródło użytkownik

głosy
40

detailCalloutAccessoryView

W dawnych czasach był to ból, ale Apple ma rozwiązać, po prostu sprawdzić dokumenty dotyczące MKAnnotationView

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

Naprawdę, to jest to. Bierze żadnej UIView.

Odpowiedział 23/07/2012 o 13:44
źródło użytkownik

głosy
13

Kontynuując od @ genialnie prostej odpowiedzi TappCandy jest, jeśli chcesz ożywić swoją bańkę w ten sam sposób, jak domyślny, ja produkowane tej metody animacji:

- (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);
            }];
        }];
    }];
}

Wygląda to dość skomplikowane, ale tak długo, jak punkt swojej objaśnienia bańki ma być środkowy dolny, należy po prostu być w stanie zastąpić myBubbleWidthi myBubbleHeightze swoim rozmiarem do jego pracy. I pamiętaj, aby upewnić się, że subviews mają swoją autoResizeMaskwłasność ustawiony na 63 (czyli „wszystko”), aby skalować one poprawnie w animacji.

: -Joe

Odpowiedział 24/10/2011 o 13:41
źródło użytkownik

głosy
8

Okazało się, że najlepszym rozwiązaniem dla mnie. Będziesz musiał użyć trochę kreatywności, aby zrobić własne dostosowania

W swojej MKAnnotationViewpodklasy, można użyć

- (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++;
            }
        }
    }
}

A jeśli subviewjest UICalloutView, to można wkręcić się z nim, a co jest w środku.

Odpowiedział 31/08/2011 o 21:36
źródło użytkownik

głosy
6

Miałem ten sam problem. Istnieje poważne z blogu na ten temat na tym blogu http://spitzkoff.com/craig/?p=81 .

Wystarczy za pomocą MKMapViewDelegatenie pomoże tu i podklasy MKMapViewi stara się rozszerzyć istniejące funkcje również nie działa dla mnie.

Co skończyło się robi jest stworzenie moje własne CustomCalloutView, które mam na górze mojej MKMapView. Można projektować ten pogląd w dowolny sposób.

Mój CustomCalloutViewma sposób podobny do tego:


- (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];
}

Zajmuje MKAnnotationobiekt i ustawia swój własny tytuł, potem nazywa to dwie inne metody, które są dość brzydki, które dostosowują szerokość i rozmiar zawartości objaśnień, a potem czerpać bańki mowy wokół niego w prawidłowym położeniu.

Wreszcie widok jest dodawany jako podrzędny do MapView. Problem z tego rozwiązania jest to, że trudno jest utrzymać objaśnienie w prawidłowej pozycji, gdy mapa jest przewijane. Ja po prostu ukrywa się objaśnienie w metodzie delegata widokiem mapy na zmianę regionu, aby rozwiązać ten problem.

Zajęło to trochę czasu, aby rozwiązać wszystkie te problemy, ale teraz objaśnienie niemal zachowuje się jak oficjalny, ale mam to w moim stylu.

Odpowiedział 16/10/2009 o 11:35
źródło użytkownik

głosy
5

Zasadniczo rozwiązać ten problem, trzeba: a) zapobiegania bańki domyślny objaśnienia z wymyślanie. b) Sprawdź który Adnotacja został kliknięciu.

I był w stanie osiągnąć te: a) ustalanie canShowCallout NO podklasy b), MKPinAnnotationView i przesłanianie metody touchesBegan i touchesEnd.

Uwaga: Musisz obsłużyć zdarzenia dotykowe dla MKAnnotationView i nie MKMapView

Odpowiedział 20/11/2009 o 12:22
źródło użytkownik

głosy
3

Po prostu wymyślić podejścia, pomysł jest tutaj

  // 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];
    }
}

Tutaj - testview jest UIViewod wielkości formacie 320x100 - showCallout jest BOOL - [self animateIn];jest to funkcja, która ma widok animacji jak UIAlertView.

Odpowiedział 26/01/2012 o 12:08
źródło użytkownik

głosy
1

Mam wypchnięty widelec z doskonałej SMCalloutView który rozwiązuje problem z zapewnieniem niestandardowy widok dla objaśnienia i umożliwiając elastyczne i rozstawu / wysokość dość bezboleśnie. Jeszcze kilka dziwactw do pracy, ale jest to dość funkcjonalne do tej pory:

https://github.com/u10int/calloutview

Odpowiedział 18/10/2012 o 00:04
źródło użytkownik

głosy
1

Można użyć leftCalloutView ustawienie annotation.text do @”"

Poniżej znajduje się przykładowy kod:

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 = @" ";            
Odpowiedział 14/04/2011 o 10:18
źródło użytkownik

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