Jak přizpůsobit popisku bubliny pro MKAnnotationView?

hlasů
87

Jsem v současné době pracuje s mapkit a jsem přilepená.

Mám výhled na zakázku anotace já používám, a chci použít vlastnost obrazu zobrazit bod na mapě se svou vlastní ikonou. Mám v pořádku. Ale co bych taky chtěl udělat, je přepsat výchozí popisku pohled (bublinu, která ukazuje nahoru s titulem / titulků, když je ikona anotace dotkla). Chci, aby bylo možné kontrolovat popisku sám: mapkit poskytuje přístup pouze k levému a pravému pomocné zobrazení popisky, ale žádný způsob, jak zajistit si vlastní názor na popisku bubliny, nebo, aby to mělo nulovou velikost, nebo cokoliv jiného.

Můj nápad byl přepsat selectAnnotation / deselectAnnotation do mého MKMapViewDelegate, a pak nakreslit svůj vlastní vlastní názor tím, že volání do mého vlastního anotace pohledu. To funguje, ale pouze tehdy, pokud canShowCalloutje nastavena na hodnotu YESv mé vlastní třídy anotace pohledu. Tyto metody nejsou volal, když mám nastaveno na NO(což je to, co chci, takže výchozí popisku bublina není vypracován). Takže nemám žádný způsob, jak zjistit, jestli uživatel dotkl mého bodu na mapě (vybrané) a nebo se dotkl bod, který není součástí mé názory anotace (delected ji), aniž by výchozí popisku bublina zobrazení objeví.

Zkoušel jsem šel jinou cestou a jen zabývat se všemi dotekové události sám do mapy, a já nedokážu dostat tuto práci. Četl jsem další příspěvky vztahující se k chytání dotekové události v zobrazení mapy, ale nejsou přesně to, co chci. Existuje způsob, jak kopat do zobrazení mapy k odstranění popisku bubliny před tažením? Jsem na rozpacích.

Nějaké návrhy? Mám něco chybí jasné?

Položena 14/10/2009 v 13:02
zdroj uživatelem
V jiných jazycích...                            


9 odpovědí

hlasů
53

Tam je ještě jednodušší řešení.

Vytvořit vlastní UIView(pro vaši popisku).

Potom vytvořit podtřídu MKAnnotationViewa přepsat setSelectednásledovně:

- (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, odvedená práce.

Odpovězeno 05/08/2011 v 12:16
zdroj uživatelem

hlasů
40

detailCalloutAccessoryView

Za dávných časů to bylo bolest, ale Apple vyřešil, jen kontrolovat dokumenty týkající se MKAnnotationView

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

Opravdu, to je ono. Přijme jakékoliv UIView.

Odpovězeno 23/07/2012 v 13:44
zdroj uživatelem

hlasů
13

Pokračující dále @ geniálně jednoduchá odpověď TappCandy je, pokud chcete animovat bublinu stejným způsobem jako výchozí jedné, jsem produkoval tento způsob animace:

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

Vypadá to docela složité, ale tak dlouho, dokud bod vaší popisku bubliny je navržen tak, aby byl střed-dno, měli byste prostě být schopen nahradit myBubbleWidtha myBubbleHeights vlastní velikostí, aby mohla fungovat. A pamatujte si, aby se ujistil vaše subviews mají jejich autoResizeMaskvlastnost nastavena na hodnotu 63 (tj „all“) tak, že měřítko správně v animaci.

: -Joe

Odpovězeno 24/10/2011 v 13:41
zdroj uživatelem

hlasů
8

Zjištěno, že se jedná být nejlepším řešením pro mě. Budete muset použít nějaký kreativitu dělat své vlastní úpravy

Ve vaší MKAnnotationViewpodtřídy, můžete použít

- (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 pokud subviewje UICalloutView, pak si můžete šroub si s ním, a to, co je uvnitř.

Odpovězeno 31/08/2011 v 21:36
zdroj uživatelem

hlasů
6

Měl jsem stejný problém. Tam je vážný o příspěvcích o tomto tématu na tomto blogu http://spitzkoff.com/craig/?p=81 .

Jen pomocí MKMapViewDelegatenepomůže vám tady a subclassing MKMapViewa snaží se rozšířit stávající funkce také nefunguje pro mě.

To, co jsem skončil dělat, je vytvořit svůj vlastní CustomCalloutView, který Mám na vrcholu své MKMapView. Můžete styl tento názor v žádném případě chcete.

My CustomCalloutViewmá metodu podobnou této:


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

Trvá MKAnnotationobjekt a nastaví svůj vlastní název, poté volá dvě další metody, které jsou docela ošklivý, které upraví šířku a velikost obsahu popisky a potom nakreslete bublinu kolem něj ve správné poloze.

Nakonec je pohled přidán jako subview k MapView. Problémem tohoto řešení je, že je těžké udržet popisku ve správné poloze, kdy je zobrazení mapy posouvat. Jsem jen skrývá popisek v metodě shlédnutí mapa delegáta na změnu regionu, aby tento problém vyřešit.

Trvalo nějaký čas, jak vyřešit všechny tyto problémy, ale nyní callout téměř chová jako ten oficiální, ale mám to ve svém vlastním stylu.

Odpovězeno 16/10/2009 v 11:35
zdroj uživatelem

hlasů
5

V podstatě to vyřešit, je třeba: a) zabránit výchozí popisku bubliny z blíží. b) Zjistit, který anotace se klikne.

Byl jsem schopen dosáhnout tyto: a) stanovení canShowCallout NO b) podtříd, MKPinAnnotationView a potlačením metod touchesBegan a touchesEnd.

Poznámka: Je třeba zvládnout události dotyku pro MKAnnotationView a nikoliv MKMapView

Odpovězeno 20/11/2009 v 12:22
zdroj uživatelem

hlasů
3

Jen jsem přišel s přístupem, myšlenka tady je

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

Zde - testview je UIViewo velikosti velikost 320x100 - showCallout je BOOL - [self animateIn];je funkce, která dělá animace pohled podobné UIAlertView.

Odpovězeno 26/01/2012 v 12:08
zdroj uživatelem

hlasů
1

Já jsem tlačil na můj vidlici vynikající SMCalloutView, který řeší problém se zajištěním vlastní zobrazení pro popisky a umožňuje flexibilní šířky / výšky docela bezbolestně. Ještě nějaké vtípky přijít, ale je to docela funkční tak daleko:

https://github.com/u10int/calloutview

Odpovězeno 18/10/2012 v 00:04
zdroj uživatelem

hlasů
1

Můžete použít leftCalloutView, nastavení annotation.text k @“"

Níže najdete příklad kódu:

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 = @" ";            
Odpovězeno 14/04/2011 v 10:18
zdroj uživatelem

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