2

我有一个条件语句来在下面的方法中添加地图注释图标/图钉。我遇到的问题是地图上填充了所有相同的图标。它应该检测猫 ID 并根据检测到的猫 ID 显示图标。我不确定问题出在哪里,因为这在 iOS 6 中确实有效,现在在 iOS 7 中,地图只显示所有相同的注释图标图像。

- (MKAnnotationView *) mapView:(MKMapView *)mapingView viewForAnnotation:(id <MKAnnotation>) annotation {
annView = nil;
if(annotation != mapingView.userLocation)
{
    
    static NSString *defaultPinID = @"";
    annView = (MKAnnotationView *)[mapingView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
    if ( annView == nil )
        annView = [[MKAnnotationView alloc]
                   initWithAnnotation:annotation reuseIdentifier:defaultPinID] ;
    
    
    UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [rightButton setTitle:annotation.title forState:UIControlStateNormal];
 
    annView.rightCalloutAccessoryView = rightButton;
    
    MyAnnotation* annotation= [MyAnnotation new];
    
    annotation.catMapId = categoryIdNumber;
    NSLog(@"categoryIdNumber %@",categoryIdNumber);
    NSLog(@"annotation.catMapId %@",annotation.catMapId);

    
        if (annotation.catMapId == [NSNumber numberWithInt:9]) {
            annView.image = [UIImage imageNamed:@"PIN_comprare.png"];
            
            NSLog(@"annview 9");
            
        }
        
        else if (annotation.catMapId == [NSNumber numberWithInt:10]) {
            annView.image = [UIImage imageNamed:@"PIN_mangiare.png"];
            
            NSLog(@"annview 10");
            
        }
        
        else if (annotation.catMapId == [NSNumber numberWithInt:11]) {
            annView.image = [UIImage imageNamed:@"PIN_visitare.png"];
            
            NSLog(@"annview 11");
            
        }
        
        else if (annotation.catMapId == [NSNumber numberWithInt:12]) {
            annView.image = [UIImage imageNamed:@"PIN_vivere.png"];
            
            NSLog(@"annview 12");
            
        }
 
    annView.canShowCallout = YES;
    
}

return annView;

}

在此处输入图像描述

4

4 回答 4

1

在末尾添加这一行:

annView.annotation = annotation;
于 2013-10-22T10:19:46.163 回答
1

如果,如您所说,“这在 iOS 6 中确实有效”,您应该认为它确实(或似乎)幸运,并且在任何版本下都不应依赖这种设置注释图像的方法。

尽管@Ar Maannotation应该设置注释视图的属性是正确的(以防视图被重新使用),但这并不能解决主要问题。

注释视图的image设置基于其值categoryIdNumber似乎是委托方法之外的某个变量。viewForAnnotation

不能假设:

  1. viewForAnnotation打电话后会马上打电话addAnnotation。即使在 iOS 6 或更早版本中,也不能保证这一点。
  2. viewForAnnotation每个注释只会被调用一次。当用户平移或缩放地图并且注释返回到屏幕上时,可以为同一个注释多次调用委托方法。
  3. viewForAnnotation将按照添加注释的相同顺序调用。这是第 1 点和第 2 点的结果。

我假设就在您调用之前addAnnotationcategoryIdNumber已正确设置,然后基于上述不正确的假设,viewForAnnotation用于categoryIdNumber设置图像。

正在发生的事情是viewForAnnotation在所有或部分addAnnotation调用完成后的某个时间被地图视图调用,此时categoryIdNumber可能是与添加的最后一个注释相关的值,并且所有注释都使用适用于最后一个注释的图像。


要解决此问题(无论iOS 版本如何),您必须在调用之前categoryIdNumber将正确的值放入每个注释对象中。addAnnotation

看起来您的注释类是MyAnnotation并且您已经有一个catMapId属性。

您必须在调用之前在注释中设置此属性addAnnotation- 而不是viewForAnnotation为时已晚的方法中设置。(顺便说一句,您在方法中创建了一个没有意义的MyAnnotation对象。)viewForAnnotation


因此,您在哪里创建和添加注释(不在 中viewForAnnotation):

MyAnnotation* myAnn = [[MyAnnotation alloc] init];
myAnn.coordinate = ...
myAnn.title = ...
myAnn.catMapId = categoryIdNumber;  // <-- set catMapId BEFORE addAnnotation
[mapView addAnnotation:myAnn];

那么里面的代码viewForAnnotation应该是这样的:

- (MKAnnotationView *) mapView:(MKMapView *)mapingView viewForAnnotation:(id <MKAnnotation>) annotation
{
    annView = nil;
    if(annotation != mapingView.userLocation)
    {

        static NSString *defaultPinID = @"MyAnnId";
        annView = (MKAnnotationView *)[mapingView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
        if ( annView == nil )
        {
            annView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] ;
            annView.canShowCallout = YES;
        }
        else
        {
            //view is being re-used, re-set annotation to current...
            annView.annotation = annotation;
        }

        UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        [rightButton setTitle:annotation.title forState:UIControlStateNormal];

        annView.rightCalloutAccessoryView = rightButton;


        //Make sure we have a MyAnnotation-type annotation
        if ([annotation isKindOfClass:[MyAnnotation class]])
        {
            //Do not CREATE a local MyAnnotation object here.
            //Instead, get the catMapId from the annotation object
            //that was PASSED INTO the delegate method.
            //MyAnnotation* annotation= [MyAnnotation new];
            //annotation.catMapId = categoryIdNumber;

            MyAnnotation *myAnn = (MyAnnotation *)annotation;

            //The value of the external variable categoryIdNumber is irrelevant here.
            //NSLog(@"categoryIdNumber %@",categoryIdNumber);

            NSLog(@"myAnn.catMapId %@",myAnn.catMapId);


            //Put the NSNumber value into an int to simplify the code below.
            int myAnnCatMapId = [myAnn.catMapId intValue];

            NSString *imageName = nil;
            switch (myAnnCatMapId)
            {
                case 9:
                {
                    imageName = @"PIN_comprare.png";
                    break;
                }

                case 10:
                {
                    imageName = @"PIN_mangiare.png";
                    break;
                }

                case 11:
                {
                    imageName = @"PIN_mangiare.png";
                    break;
                }

                case 12:
                {
                    imageName = @"PIN_vivere.png";
                    break;
                }

                default:
                {
                    //set some default image for unknown cat ids...
                    imageName = @"default.png";
                    break;
                }
            }

            annView.image = [UIImage imageNamed:imageName];

            NSLog(@"annview %d", myAnnCatMapId);
        }
    }

    return annView; 
}
于 2013-10-22T13:17:41.820 回答
0

同样的麻烦,对我来说决定不使用

pinView.animatesDrop   = YES;

自定义图标对我来说不适用于动画下降。

于 2014-04-09T08:21:47.247 回答
0

如果有人需要使用 MapView 注释作为 tableView,即有一个点数组显示在地图上。

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    let identifier = MKMapViewDefaultAnnotationViewReuseIdentifier
    if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? TrailAnnotationView {
            ///TrailAnnotation has an object of type trail ( can be any model you ///want ). and so is TrailAnnotationView
///inside TrailAnnotationView we extract data from trail and display it.
        annotationView.trail = (annotation as? TrailAnnotation)?.trail
        annotationView.annotation = annotation
        return annotationView
    }
    let annotationView = TrailAnnotationView(annotation: annotation, reuseIdentifier: identifier)
    annotationView.trail = (annotation as? TrailAnnotation)?.trail
    annotationView.canShowCallout = true
    return annotationView
}

这是一个 TrailAnnotationView

protocol AnnotationViewProtocol {
    func didTapOnAnnotation()
}

class TrailAnnotationView: MKPinAnnotationView {

/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
    // Drawing code
}
*/

var trail: TrailModel? = nil


override var annotation: MKAnnotation? { didSet { configureDetailView() } }

override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
    super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
    configure()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    configure()
}

}

private extension TrailAnnotationView {
    func configure() {
        canShowCallout = true
        configureDetailView()
    }

func configureDetailView() {
    guard let annotation = annotation else { return }

    let rect = CGRect(origin: .zero, size: CGSize(width: 300, height: 200))

    let snapshotView = UIView()
    snapshotView.translatesAutoresizingMaskIntoConstraints = false

    if let trail = self.trail, !trail.imageUrl.isEmpty {
        AppUtils.sharedInstance.fetchImageFor(path: trail.imageUrl) { (image) in
            guard let imageData = image else { return }
            DispatchQueue.main.async {
                let imageView = UIImageView(frame: rect)
                imageView.image = imageData
                snapshotView.addSubview(imageView)
            }
        }
    } else {
        let options = MKMapSnapshotter.Options()
        options.size = rect.size
        options.mapType = .satelliteFlyover
        options.camera = MKMapCamera(lookingAtCenter: annotation.coordinate, fromDistance: 250, pitch: 65, heading: 0)

        let snapshotter = MKMapSnapshotter(options: options)
        snapshotter.start { snapshot, error in
            guard let snapshot = snapshot, error == nil else {
                print(error ?? "Unknown error")
                return
            }

            let imageView = UIImageView(frame: rect)
            imageView.image = snapshot.image
            snapshotView.addSubview(imageView)
        }
    }

    detailCalloutAccessoryView = snapshotView
    NSLayoutConstraint.activate([
        snapshotView.widthAnchor.constraint(equalToConstant: rect.width),  
        snapshotView.heightAnchor.constraint(equalToConstant: rect.height)
    ])
}
}
于 2020-06-16T17:13:23.883 回答