webentwicklung-frage-antwort-db.com.de

Wie kann ich 2 Textzeilen für den Untertitel von MKAnnotation anzeigen und das Bild für die Schaltfläche auf der rechten Seite ändern?

Ich sehe mir Apples MapCallouts-Beispiel für Kartenanmerkungen und Beschriftungen an (== Blasen, die angezeigt werden, wenn Sie auf eine Stecknadel klicken). Jede Anmerkung dort hat Koordinaten, Titel und Untertitel. Ich möchte Untertitel in 2 Zeilen anzeigen, ich habe versucht mit:

- (NSString *)subtitle
{
return @"Founded: June 29, 1776\nSecond line text";
}

aber der Text "Zweiter Zeilentext" bleibt in einer Zeile und macht die Blase breiter.

enter image description here

Ich möchte auch das Bild der Schaltfläche in ein eigenes ändern. Der Code, mit dem die Schaltfläche festgelegt wird, sieht derzeit folgendermaßen aus:

UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

Irgendwelche Ideen?

EDIT: Ich habe 7KV7's Rat versucht. Der Knopfwechsel ist erfolgreich, aber ich kann immer noch keine Untertitel in 2 Zeilen bekommen. Mein Code:

MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc]
                                        initWithAnnotation:annotation reuseIdentifier:BridgeAnnotationIdentifier] autorelease];
        customPinView.pinColor = MKPinAnnotationColorPurple;
        customPinView.animatesDrop = YES;


        // Button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(0, 0, 23, 23);
        button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
        button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

        //UIEdgeInsets titleInsets = UIEdgeInsetsMake(7.0, -20.0, 7.0, 7.0);
        //button.titleEdgeInsets = titleInsets;

        [button setImage:[UIImage imageNamed:@"ic_phone_default.png"] forState:UIControlStateNormal];
        //[button setImage:[UIImage imageNamed:@"ic_phone_selected.png"] forState:UIControlStateSelected];
        [button setImage:[UIImage imageNamed:@"ic_phone_selected.png"] forState:UIControlStateHighlighted];
        [button addTarget:self action:@selector(showDetails:) forControlEvents:UIControlEventTouchUpInside];

        customPinView.rightCalloutAccessoryView = button;

        //two labels
        UIView *leftCAV = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,50)];
        //[leftCAV addSubview : button];
        UILabel *l1=[[UILabel alloc] init];
        l1.frame=CGRectMake(0, 15, 50, 50);
        [email protected]"First line of subtitle"; 
        l1.font=[UIFont fontWithName:@"Arial Rounded MT Bold" size:(10.0)];

        UILabel *l2=[[UILabel alloc] init];
        l2.frame=CGRectMake(0, 30, 50, 50);
        [email protected]"Second line of subtitle";
        l2.font=[UIFont fontWithName:@"Arial Rounded MT Bold" size:(10.0)];
        [leftCAV addSubview : l1];
        [leftCAV addSubview : l2];
        customPinView.leftCalloutAccessoryView = leftCAV;
        //customPinView.
        customPinView.canShowCallout = YES;

        return customPinView;

Ich bekomme das:

enter image description here

14
DixieFlatline
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{   
    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];

    // Button
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 23, 23);
button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

[button setImage:[UIImage imageNamed:yourImageName] forState:UIControlStateNormal];
[advertButton addTarget:self action:@selector(buttonPress:) forControlEvents:UIControlEventTouchUpInside];

annView.rightCalloutAccessoryView = button;


    // Image and two labels
    UIView *leftCAV = [[UIView alloc] initWithFrame:CGRectMake(0,0,23,23)];
    [leftCAV addSubview : yourImageView];
    [leftCAV addSubview : yourFirstLabel];
    [leftCAV addSubview : yourSecondLabel];
    annotationView.leftCalloutAccessoryView = leftCAV;

    annotationView.canShowCallout = YES;

    return pin;
}

UPDATE

Der Standardstil für Anmerkungen unterstützt nur den Titel und den Untertitel. Weder Titel noch Untertitel dürfen Zeilenumbrüche enthalten. Sie können dies nicht ohne Unterklassen tun.

So verwenden Sie einen Beispielcode für eine benutzerdefinierte Ansicht:

http://developer.Apple.com/library/ios/#samplecode/WeatherMap/Introduction/Intro.html

Ich denke auch, dass es ein Problem in Ihrem Code gibt

UILabel *l1=[[UILabel alloc] init];
l1.frame=CGRectMake(0, 15, 50, 50);
[email protected]"First line of subtitle"; 
l1.font=[UIFont fontWithName:@"Arial Rounded MT Bold" size:(10.0)];

UILabel *l2=[[UILabel alloc] init];
l2.frame=CGRectMake(0, 30, 50, 50);
[email protected]"Second line of subtitle";
l2.font=[UIFont fontWithName:@"Arial Rounded MT Bold" size:(10.0)];
[leftCAV addSubview : l1];
[leftCAV addSubview : l2];

l1 hat einen Rahmen (0, 15, 50, 50) und l2 hat (0, 30, 50, 50). Überlappen sich diese beiden nicht? Ich meine, l1 fängt bei y = 15 an und hat eine Höhe von 50. Wenn l2 bei 30 anfängt, kann es zu Überlappungen kommen

5
visakh7

bitte benutzen Sie dies

 - (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {

        if ([annotation isKindOfClass:[MKUserLocation class]])
            return nil;
        if ([annotation isKindOfClass:[CustomAnnotation class]]) {
            CustomAnnotation *customAnnotation = (CustomAnnotation *) annotation;

            MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomAnnotation"];

            if (annotationView == nil)
                annotationView = customAnnotation.annotationView;
            else
                annotationView.annotation = annotation;

            //Adding multiline subtitle code 

            UILabel *subTitlelbl = [[UILabel alloc]init];
            subTitlelbl.text = @"sri ganganagar this is my home twon.sri ganganagar this is my home twon.sri ganganagar this is my home twon.  ";

            annotationView.detailCalloutAccessoryView = subTitlelbl;

            NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:subTitlelbl attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:150];

             NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:subTitlelbl attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:0];
            [subTitlelbl setNumberOfLines:0];
            [subTitlelbl addConstraint:width];
            [subTitlelbl addConstraint:height];




            return annotationView;
        } else
            return nil;
    }

 enter image description here

5
balkaran singh

So habe ich es erreicht, ohne die Anmerkungsansicht zu unterteilen oder undokumentierte APIs zu verwenden:

MKAnnotationView* pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomPinAnnotationView"];

// Add a custom view to the the callout to allow mutli-line text
UIView *calloutView = [[UIView alloc] initWithFrame:CGRectMake(0, 10, 250, 250)];
UIView *calloutViewHeight = [[UIView alloc] initWithFrame:CGRectMake(0, 10, 1, 250)]; // The reason for this will become apparent below
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 250, 21)];
[title setText:<<your single-line title text>>];
[calloutView addSubview:title];
UILabel *subtitle = [[UILabel alloc] initWithFrame:CGRectMake(10, 35, 250, 250)];
[subtitle setNumberOfLines:0];
[subtitle setText:<<your multi-line title text>>];
CGSize subtitleSize = [subtitle sizeThatFits:CGSizeMake(250, 250)];
[subtitle setFrame:CGRectMake(10, 35, 250, subtitleSize.height)];
[calloutView addSubview:subtitle];
[calloutView setFrame:CGRectMake(0, 10, 250, 35+subtitleSize.height+10)];
[calloutViewHeight setFrame:CGRectMake(0, 0, 1, 35+subtitleSize.height+10)];
pinView.leftCalloutAccessoryView = calloutView;
pinView.rightCalloutAccessoryView = calloutViewHeight;  // The height of the callout is calculated by the right accessory *not* the left, so this fake view is required

Sie können die Schriftart/Farbe des Texts anpassen, indem Sie title und subtitle entsprechend anpassen.

Sicher, es ist ein bisschen schwierig, aber es erzielt die gewünschten Ergebnisse ohne Unterklassen und ermöglicht es Ihnen, beliebige zusätzliche Schaltflächen/Bilder hinzuzufügen, die Sie calloutView hinzufügen möchten wünschen, solange Sie die Höhe behalten).

3
Karl White

Zwei Zeilen in einem Callout können nicht ausgeführt werden, ohne auf nicht unterstützte APIs zuzugreifen. In diesem Fall wird Ihre App abgelehnt.

Wenn Sie ein iPad haben, können Sie ein Beispiel für ein benutzerdefiniertes Callout sehen. Ihre Beschriftung verwandelt sich in eine Popout-Ansicht, die wie eine Beschriftung an der Kartenposition haftet. So kann es sein, dass Apple in der nächsten Version von iOS die Callout-API erweitert. Im Moment bleiben Sie bei einzeiligen Untertiteln.

Wenn Sie dies wirklich tun möchten, müssen Sie Ihre eigene Callout-Klasse erstellen und sie beim Scrollen an der Karte festhalten. Das wäre wahrscheinlich schwierig.

Eine andere Idee ist, eine Legende vorzutäuschen. Erstellen Sie eine benutzerdefinierte Anmerkungsansicht mit 2 Ansichten. Der erste ist ein Kartenstift. Die zweite ist eine Legende. Wenn der Stift berührt wird, können Sie die Callout-Ansicht einblenden. Es wird die "Pop" -Animation fehlen, aber Sie können so viele Zeilen einfügen, wie Sie möchten.

Ich habe das noch nie ausprobiert und es hört sich so an, als gäbe es eine Menge Details, um es richtig zu machen, aber es könnte Ihnen einen Anfang geben.

2
nevan king

Zum Einstellen der Taste können Sie den folgenden Code verwenden

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    MKAnnotationView *x=[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"someIdentifier"];
    UIButton *button=[UIButton buttonWithType:UIButtonTypeCustom];
    //set the target, title, image etc.
    [x setRightCalloutAccessoryView:button];
    return [x autorelease];
}
1
Stefan

Dies kann in 9 Schritten erfolgen.

Ich habe ein Etikett erstellt und es der Eigenschaft annotationView?.detailCalloutAccessoryView hinzugefügt (Schritt 5). Ich habe auch den Text des Etiketts auf den Text annotation.subtitle gesetzt (Schritt 2 & Schritt 4). Ich stelle den .numberOfLines = 0 des Etiketts ein. Dadurch wird der Untertitel erweitert, je nachdem, wie viele Zeilen benötigt werden (auf 2 setzen, wenn Sie nur 2 benötigen).

Für die Schaltfläche habe ich einen UIButton erstellt und dessen Typ auf .detailDisclosure gesetzt (Schritt 7). Anschließend setze ich die Bildeigenschaft der Schaltfläche auf das benutzerdefinierte Bild, das ich verwenden möchte (Schritt 8). Zuletzt habe ich die Schaltfläche auf die Eigenschaft .rightCalloutAccessoryView von annotationView gesetzt (Schritt 9).

Ich versetze auch die Eigenschaft .calloutOffset von annotationView (Schritt 6). Ich habe den Offset von Ray Wenderlich

Schritte finden Sie in den Kommentaren über dem Code

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

    if annotation.isKindOfClass(MKUserLocation) {
        return nil
    }

    let reuseIdentifier = "reuseIdentifier"

    var annotationView = mapView.mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? MKPinAnnotationView

    if annotationView == nil {

        annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)

        // 1. set the annotationView's canShowCallout property to true
        annotationView?.canShowCallout = true

        // 2. get the subtitle text from the annontation's subtitle property
        let subtitleText = annotation.subtitle ?? "you have no subtitle"

        // 3. create a label for the subtitle text
        let subtitleLabel = UILabel()
        subtitleLabel.translatesAutoresizingMaskIntoConstraints = false

        // 4. set the subtitle's text to the label's text property and number of lines to 0
        subtitleLabel.text = subtitleText
        subtitleLabel.numberOfLines = 0

        // 5. set the annotation's detailCalloutAccessoryView property to the subtitleLabel
        annotationView?.detailCalloutAccessoryView = subtitleLabel

        // 6. offset the annotationView's .calloutOffset property
        annotationView?.calloutOffset = CGPoint(x: -5, y: 5)

        // 7. create a button and MAKE SURE to set it's type to .detailDisclosure or it won't appear
        let button = UIButton(type: .detailDisclosure)

        // 8. set the button's image to whatever custom UIImage your using
        button.setImage(UIImage(named: "yourCustomImage"), for: .normal)

        // 9. set the button to the annotationView's .rightCalloutAccessoryView property
        annotationView?.rightCalloutAccessoryView = button

    } else {
        annotationView!.annotation = annotation
    }

    return annotationView
}
0
Lance Samaria

Ergebnisbild

Diese Lösung setzt "berechtigten" Text, hoffe nützlich zu sein:

Swift 3:

import MapKit

extension MKAnnotationView {
func setCustomLines(customLines lines: [String]) {
    if lines.count <= 0 {
        return
    }

    // get longest line
    var longest = NSString()
    if let max = lines.max(by: { $1.characters.count > $0.characters.count }) {
        longest = max as NSString
    }
    else {
        fatalError("Can't get longest line.")
    }

    // get longest text width
    let font = UIFont.systemFont(ofSize: 15.0)
    let width = (longest.size(attributes: [NSFontAttributeName: font])).width

    // get text from lines
    var text = lines.first
    for i in 1..<lines.count {
        text = text! + " " + lines[i]
    }

    // label
    let label = UILabel()
    label.text = text
    label.font = font
    label.numberOfLines = lines.count
    label.textAlignment = .justified

    // set width of label
    let con = NSLayoutConstraint(item: label, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: width)
    label.addConstraint(con)

    self.detailCalloutAccessoryView = label
}
}
0
Luat Vu Dinh

Mit der öffentlichen API ist dies nicht möglich, und Sie müssen Ihre eigene benutzerdefinierte Anmerkungsansicht erneut implementieren.
Sie können sich diesen Code ansehen, der die Anmerkungsansicht neu implementiert, aber den Standard-iOS-Code nachahmt, und ihn dann an Ihre eigenen Bedürfnisse anpassen:
http://blog.asolutions.com/2010/09/building-custom-map-annotation-callouts-part-1/

0
yonel