how to show multiple lines in MKAnnotation with autolayout?

ⅰ亾dé卋堺 提交于 2019-12-30 02:29:07

问题


i am using mapkit how i can multiple line in MKAnnotation view.

Every annotation there has title and subtitle. how i show sub title with multiple line with the help of auto layout ?

i found it's Answer .plz try my answer. we just need to do code in

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

}

here i show the idea how to use autolayout with MKAnnotation .


回答1:


extension for adding multiple lines:

import MapKit // must import MapKit for MKAnnotationView to get recognized

extension MKAnnotationView {

    func loadCustomLines(customLines: [String]) {
        let stackView = self.stackView()
        for line in customLines {
            let label = UILabel()
            label.text = line
            stackView.addArrangedSubview(label)
        }
        self.detailCalloutAccessoryView = stackView
    }



    private func stackView() -> UIStackView {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        stackView.alignment = .fill
        return stackView
    }
}

using:

view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.loadCustomLines(customLines: ["qqqq", "wwww", "eee"])



回答2:


we can show multiple line in MKAnnotation view With the help of auto layout

it's very simple.

in objective c

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

output

For Swift

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

        let identifier = "MyPin"

        if annotation.isKindOfClass(MKUserLocation) {
            return nil
        }

        var annotationView: MKPinAnnotationView? = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) as? MKPinAnnotationView

        if annotationView == nil {

            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView?.canShowCallout = true

              let label1 = UILabel(frame: CGRectMake(0, 0, 200, 21))
            label1.text = "Some text1 some text2 some text2 some text2 some text2 some text2 some text2"
             label1.numberOfLines = 0
              annotationView!.detailCalloutAccessoryView = label1;

            let width = NSLayoutConstraint(item: label1, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.LessThanOrEqual, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 200)
            label1.addConstraint(width)


            let height = NSLayoutConstraint(item: label1, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 90)
            label1.addConstraint(height)



        } else {
            annotationView!.annotation = annotation
        }
        return annotationView
    }


}

here i use NSLayoutConstraint

i programatically create a label. add the constraint on it and then add the label in detailCalloutAccessoryView of MKAnnotationView.




回答3:


Using auto layout you can type something like:

let subtitleLabel = UILabel()
subtitleLabel.text = "Location updated\n" + dateFormatter.string(from: date)
subtitleLabel.numberOfLines = 0
subtitleLabel.font = UIFont.systemFont(ofSize: 14)
subtitleLabel.textColor = .lightGray
subtitleLabel.setContentCompressionResistancePriority(.required, for: .vertical)

annotationView?.detailCalloutAccessoryView = subtitleLabel



回答4:


5 steps

I created a label and added it to the annotationView?.detailCalloutAccessoryView property (step 5). I also set the label's text to the annotation.subtitle text (step 2 & step 4) and .numberOfLines = 0

Steps are in the comments above the 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

    } else {
        annotationView!.annotation = annotation
    }

    return annotationView
}



回答5:


And If you want to have the multi label clicked to go somewhere, you would need to: 1- create programmatically created UITapGestureRecognizer on the AnnotationView. 2- create the function to pass to the gesture selector. The function takes a sender parameter of type UIGestureRecognizer. Have an if statement that makes sure that you have the canshowcallout to true so you only click when it's showing to avoid clicking on the actual pin itself.

So in my case i had this scenario. This may help someone: - tableView that has cells of different locations populated - top half of the screen is map that shows your the pin of each location - As you click on the table view or the pins in the map, the map center itself and shows you the pin callout view, which is a small view with a picture and the name of the location in multi-lines breaks if the name of location is long to avoid truncating tails. - Because the index was passed and used everywhere in our code to determine the which location was clicked , i had to use it also to show the right name in the callout of the location that was clicked. The problem that i was having is the click on the label since i used annotationView.detailCalloutAccessoryView = myLabel . seems like when . you use the detail one and not the right or left, you don't get the click even from the controlTapped map delegate function. So i had to do the following inside the gesture selector function i talked about previously: make sure that you are doing somekind of guard or if let with comma on these checks all together. - check for the view tag by doing let tag = sender.view.tag - get the view as MKPinAnnotationView: let view = sender.view as? MKPointAnnotationView - check for callout to make sure it's showing first by doing: view.canShowCallout - then inside the curly braces of the if or guard you do let index = tag and pass in the index to my function that perform the action on the view to segue to the native apple map after clicking on the annotationView.

  • after all that in annotationFor View delegate function as i said before pass in this function to the gesture recognizer selector



回答6:


let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
label1.text = "Some text1 some text2 some text2 some text2 some text2 some text2 some text2"
label1.numberOfLines = 0
annotationView!.detailCalloutAccessoryView = label1;

let width = NSLayoutConstraint(item: label1, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.lessThanOrEqual, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 200)
        label1.addConstraint(width)


let height = NSLayoutConstraint(item: label1, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 90)
        label1.addConstraint(height)


来源:https://stackoverflow.com/questions/40214778/how-to-show-multiple-lines-in-mkannotation-with-autolayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!