how to show multiple lines in MKAnnotation with autolayout?

后端 未结 6 1868
臣服心动
臣服心动 2020-12-30 17:21

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

相关标签:
6条回答
  • 2020-12-30 17:55
    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)
    
    0 讨论(0)
  • 2020-12-30 17:57

    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
    }
    
    0 讨论(0)
  • 2020-12-30 17:57

    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
    0 讨论(0)
  • 2020-12-30 17:59

    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
    
    0 讨论(0)
  • 2020-12-30 18:07

    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.

    0 讨论(0)
  • 2020-12-30 18:15

    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"])
    
    0 讨论(0)
提交回复
热议问题