代码之家  ›  专栏  ›  技术社区  ›  user2588945

地图注释显示所有点的所有相同图像/接点

  •  2
  • user2588945  · 技术社区  · 12 年前

    我有一个条件语句,可以在下面的方法中添加地图注释图标/引脚。我遇到的问题是,地图上填充了所有相同的图标。它应该检测到猫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;
    

    }

    enter image description here

    4 回复  |  直到 6 年前
        1
  •  1
  •   user467105 user467105    12 年前

    如果,正如你所说,“这在iOS 6中确实有效”,你应该考虑一下 相当地 幸运的是,它确实做到了(或似乎做到了),这种设置注释图像的方法在任何版本下都不应该依赖。

    尽管@Ar-Ma正确地认为注释视图 annotation 属性(以防视图被重新使用),这不会解决主要问题。

    注释视图的 image 基于的值设置 categoryIdNumber 这似乎是一些变量 外部 这个 viewForAnnotation 委托方法。

    不能 假设:

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

    我想就在你打电话之前 添加注释 这个 类别ID编号 被正确地设置,然后基于上述不正确的假设, 查看注释 使用 类别ID编号 以设置图像。

    现在的情况是 查看注释 正在被地图视图调用 添加注释 调用在哪个点完成 类别ID编号 可能是与添加的最后一个注释相关的值,并且所有注释都使用适用于最后一个批注的图像。


    要解决此问题( 不管 iOS版本的),您必须将 类别ID编号 值输入到每个注释对象中 之前 使命感 添加注释 .

    看起来你的注释类是 MyAnnotation 而你已经有了 catMapId 属性。

    必须在注释中设置此属性 之前 使命感 添加注释 --不是 在…内 这个 查看注释 方法为时已晚。(顺便说一句,您正在创建 我的注释 对象 在…内 这个 查看注释 这种方法毫无意义。)


    因此,在创建和添加注释的位置(不在 查看注释 ):

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

    然后代码进入 查看注释 应该是这样的:

    - (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; 
    }
    
        2
  •  1
  •   Ar Ma    12 年前

    在末尾添加此行:

    annView.annotation = annotation;
    
        3
  •  0
  •   llkenny    12 年前

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

    pinView.animatesDrop   = YES;
    

    自定义图标对我来说就是无法使用动画拖放。

        4
  •  0
  •   Gal Blank    6 年前

    如果有人需要将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)
        ])
    }
    }