Hoe de callout bel voor MKAnnotationView aanpassen?

stemmen
87

Ik ben momenteel bezig met de mapkit en zit vast.

Ik heb een aangepaste annotatie uitzicht Ik gebruik, en ik wil het pand afbeelding gebruiken om het punt op de kaart met mijn eigen pictogram. Ik heb dit werk boete. Maar wat ik zou ook graag willen doen is om de standaard bijschrift uitzicht (de bel die verschijnt met de titel / ondertitel wanneer het pictogram annotatie wordt aangeraakt) overschrijven. Ik wil in staat zijn om de callout besturen zelf: de mapkit geeft alleen toegang tot de linker en rechter bijkomende uitzicht bijschrift, maar geen manier om een ​​aangepaste weergave van de callout bel te bieden of om te geven grootte nul, of iets anders.

Mijn idee was om overschrijven selectAnnotation / deselectAnnotation in mijn MKMapViewDelegate, en dan trek ik mijn eigen aangepaste weergave door het maken van een oproep naar mijn aangepaste annotatie uitzicht. Dit werkt, maar alleen wanneer canShowCalloutis ingesteld op YESin mijn aangepaste annotatie uitzicht klasse. Deze methoden zijn niet geroepen als ik deze set aan NO(dat is wat ik wil, zodat de standaard callout bel niet is getekend). Dus ik heb geen manier om te weten als de gebruiker gesproken over mijn punt op de kaart (geselecteerd is) of aangeraakt een punt dat geen deel uitmaakt van mijn standpunten annotatie (delected it), zonder dat de standaard callout bel uitzicht opdagen.

Ik probeerde naar beneden een ander pad en gewoon omgaan met alle touch gebeurtenissen mezelf in de kaart, en ik kan niet schijnen om dit het werken te krijgen. Ik lees andere posten in verband met het vangen aanraakgebeurtenissen in de kaartweergave, maar ze zijn niet precies wat ik wil. Is er een manier om te graven in de kaartweergave op de callout bel te verwijderen voordat het tekenen? Ik weet niet.

Eventuele suggesties? Mis ik iets duidelijk?

De vraag is gesteld op 14/10/2009 om 13:02
bron van user
In andere talen...                            


9 antwoorden

stemmen
53

Er is een nog eenvoudiger oplossing.

Maak een aangepaste UIView(voor uw opvraag).

Maak vervolgens een subklasse van MKAnnotationViewen override setSelectedals volgt:

- (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, klus te klaren.

antwoordde op 05/08/2011 om 12:16
bron van user

stemmen
40

detailCalloutAccessoryView

Vroeger was dit een pijn, maar Apple heeft opgelost, kijk maar de docs op MKAnnotationView

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

Echt, dat is het. Neemt elke UIView.

antwoordde op 23/07/2012 om 13:44
bron van user

stemmen
13

Voortbouwend op @ briljant eenvoudig antwoord TappCandy's, als u wilt uw bubble animeren op dezelfde manier als de standaard, ik heb deze animatie methode geproduceerd:

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

Het ziet er vrij ingewikkeld, maar zolang het punt van uw callout bel is ontworpen voor het midden-bodem te zijn, moet je gewoon in staat zijn om te vervangen myBubbleWidthen myBubbleHeightmet je eigen maat voor het aan het werk. En vergeet niet om ervoor te zorgen dat uw subviews hebben hun autoResizeMaskeigenschap is ingesteld op 63 (dat wil zeggen "alle"), zodat ze correct schaal in de animatie.

: -Joe

antwoordde op 24/10/2011 om 13:41
bron van user

stemmen
8

Ik vond dit de beste oplossing voor mij. Je moet wat creativiteit gebruiken om uw eigen aanpassingen te doen

In uw MKAnnotationViewsubklasse, kunt u gebruik maken

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

En als de subvieween UICalloutView, dan kunt u schroef rond met het, en wat erin zit.

antwoordde op 31/08/2011 om 21:36
bron van user

stemmen
6

Ik had hetzelfde probleem. Er is een ernstig van blog posts over dit onderwerp op deze blog http://spitzkoff.com/craig/?p=81 .

Alleen met behulp van de MKMapViewDelegateu niet hier en subclassing helpen MKMapViewen proberen om de bestaande functionaliteit uit te breiden ook werkte niet voor mij.

Wat ik uiteindelijk doen is om mijn eigen te maken CustomCalloutViewdie ik heb op de top van mijn MKMapView. U kunt deze bekijken op welke manier je wilt stylen.

Mijn CustomCalloutViewheeft een methode vergelijkbaar met deze:


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

Het duurt een MKAnnotationobject en stelt zijn eigen titel, daarna roept twee andere werkwijzen die heel lelijk waarbij de breedte en omvang van de inhoud highlight passen en daarna trekt de spraakballon daaromheen op de juiste positie.

Tenslotte wordt de weergave wordt toegevoegd als subweergave de Mapview. Het probleem met deze oplossing is dat het moeilijk is om het bijschrift op de juiste positie te houden als de kaartweergave is te lezen. Ik ben gewoon verbergen van het bijschrift in de kaartweergave afgevaardigde methode op een regio verandering om dit probleem op te lossen.

Het duurde enige tijd om al die problemen op te lossen, maar nu is het bijschrift gedraagt ​​zich bijna als de officiële, maar ik heb het in mijn eigen stijl.

antwoordde op 16/10/2009 om 11:35
bron van user

stemmen
5

In principe is dit op te lossen, moet men: a) Voorkom dat de standaard callout bel uit komen. b) uit welke annotatie is geklikt.

Ik was in staat om deze te bereiken door: a) het instellen van canShowCallout naar NO b) subclassing, MKPinAnnotationView en overschrijven van de touchesBegan en touchesEnd methoden.

Let op: U moet de aanraking evenementen voor de MKAnnotationView en niet MKMapView verwerken

antwoordde op 20/11/2009 om 12:22
bron van user

stemmen
3

Ik heb net de proppen te komen met een aanpak, het idee hier is

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

Hier - testview is een UIViewvan de grootte 320x100 - showCallout is BOOL - [self animateIn];is de functie die uitzicht animatie doet alsof UIAlertView.

antwoordde op 26/01/2012 om 12:08
bron van user

stemmen
1

Ik duwde mijn vork van de uitstekende SMCalloutView dat het probleem oplost met het verstrekken van een aangepaste weergave van bijschriften en dat voorziet in flexibele breedte / hoogte vrij pijnloos. Nog enkele eigenaardigheden uit te werken, maar het is vrij functioneel tot nu toe:

https://github.com/u10int/calloutview

antwoordde op 18/10/2012 om 00:04
bron van user

stemmen
1

U kunt leftCalloutView gebruiken, het instellen van annotation.text naar @""

Hieronder een voorbeeld code:

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 = @" ";            
antwoordde op 14/04/2011 om 10:18
bron van user

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