【问题标题】:Label keeps displaying last item in plist标签一直显示 plist 中的最后一项
【发布时间】:2014-06-24 15:30:54
【问题描述】:

我正在构建一个 iPhone 应用程序,而我的标签一直在抓取我 plist 中的最后一项。应用程序的第一部分显示带有注释的地图。注释——纬度和经度以及标题也都是从同一个 plist 中提取的。

这是我的代码:

 #import "myMapViewController.h"
    #import "MapViewAnnotation.h"

    @interface myMapViewController ()
    @property NSArray *states;
    //@property NSString *nameString;
    //@property NSString *zipString;
    //@property NSString *subtitleString;
   //@property NSString *zipString;
    @end

    @implementation myMapViewController

    @synthesize mapView;



    - (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //self.mapView.showsUserLocation = YES;  //showsUserLocation = YES;
    self.mapView.delegate = self;
    [self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated: YES];
    [self.mapView addAnnotations:[self createAnnotations]];

    //[self zoomToLocation];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (NSMutableArray *)createAnnotations
{
    NSMutableArray *annotations = [[NSMutableArray alloc] init];

    NSString *path = [[NSBundle mainBundle]pathForResource:@"States" ofType:@"plist"];
    NSArray *rootLevel = [[NSMutableArray alloc]initWithContentsOfFile:path];

    int count = rootLevel.count;

    for (int i = 0; i < count; i++){

        NSDictionary *secondLevel = [rootLevel objectAtIndex:i];
        // NSArray *state = [secondLevel valueForKey:@"State"];
        NSArray *stores = [secondLevel valueForKey:@"Stores"];


        for (NSDictionary *row in stores) {
            NSString *latitude = [row objectForKey:@"Latitude"];
            NSString *longitude = [row objectForKey:@"Longitude"];
            NSString *title = [row objectForKey:@"Name"];

            NSString *nameString = [row objectForKey:@"Number"];
            NSString *zipString = [row objectForKey:@"Zip"];
            NSString *subtitle = [row objectForKey:@"Address1"];

            //Create coordinates from the latitude and longitude values
            CLLocationCoordinate2D coord;
            coord.latitude = latitude.doubleValue;
            coord.longitude = longitude.doubleValue;

            MapViewAnnotation *annotation = [[MapViewAnnotation alloc] initWithTitle:title AndCoordinate:coord AndZipString:zipString AndNameString:nameString AndSubSubtitle:subtitle];

            [annotations addObject:annotation];

            //set label


        }
    }
    return annotations;
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([[segue identifier] isEqualToString:@"showStoreDetails"])
    {



        MKAnnotationView *annotationView = sender;
        id<MKAnnotation> ann = annotationView.annotation;
       [segue.destinationViewController setNameString:ann.title];
       [segue.destinationViewController setZipString:ann.title];
        NSLog(@"log %@", annotationView.annotation.subtitle);

    }
}

- (MKAnnotationView *)mapView:(MKMapView *)sender viewForAnnotation:(id < MKAnnotation >)annotation
{
    static NSString *reuseId = @"StandardPin";

    MKPinAnnotationView *aView = (MKPinAnnotationView *)[sender
                                                         dequeueReusableAnnotationViewWithIdentifier:reuseId];

    if (annotation == mapView.userLocation){
        return nil; //default to blue dot
    }

    if (aView == nil)
    {
        aView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                                reuseIdentifier:reuseId];
        aView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        aView.canShowCallout = YES;
        //aView.animatesDrop = YES;
    }

    aView.annotation = annotation;
    return aView;
}

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
    [self performSegueWithIdentifier:@"showStoreDetails" sender:view];
    NSLog(@"accessory button tapped for annotation %@", view.annotation.title);

}

- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views {
    for(MKAnnotationView *annotationView in views) {
        if(annotationView.annotation == mv.userLocation) {
            MKCoordinateRegion region;
            MKCoordinateSpan span;

            span.latitudeDelta=0.7;
            span.longitudeDelta=0.7;

            CLLocationCoordinate2D location=mv.userLocation.coordinate;

            region.span=span;
            region.center=location;

            [mv setRegion:region animated:TRUE];
            [mv regionThatFits:region];
        }
    }
}

@end

【问题讨论】:

  • 你的意思是它只显示 plist 中的最后一个数据/记录?
  • 完全跑题了,但是您是否意识到您的 METERS_PER_MILE 常量是错误的?应该是 1609.344。
  • 根本不清楚您的问题和/或问题是什么。由于您的代码中没有提及标签,因此将哪个标签设置为最后一个值?

标签: ios plist uistoryboardsegue mkannotationview


【解决方案1】:

问题似乎是在prepareForSegue 中,您将self.nameString 发送到destinationViewController,但该变量仅包含读取的最后一项。

请注意,在calloutAccessoryControlTapped 中,您调用performSegueWithIdentifier 时将sender 作为view(即所选注释的视图但在prepareForSegue ,您没有使用sender

您应该在prepareForSegue 中使用sender 而不是self.nameString


有关详细示例,请参阅MKAnnotationView Push to View Controller when DetailDesclosure Button is Clicked

prepareForSegue 中的更新代码可能如下所示:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([[segue identifier] isEqualToString:@"showStoreDetails"])
    {
        MKAnnotationView *annotationView = sender;
        id<MKAnnotation> ann = annotationView.annotation;
        [segue.destinationViewController setNameString:ann.title];
    }
}

【讨论】:

  • 这很有意义。但是我现在无法在详细信息视图中获取更多信息。在哪里以及如何在我的 plist 中添加其他项目以传递给其他标签。
  • 在destinationViewController 中,您可以有一个方法/属性来接受整个MapViewAnnotation 对象,而不是setNameString 方法/属性。然后你可以传递它ann 而不仅仅是ann.title
  • 请原谅我正在学习所有这些内容。但我仍然无法理解我需要做什么。如何在 MapViewAnnotation 对象中包含我的所有字符串?
  • 通过“plist 中的其他项目”,我假设您的意思是特定于每个注释的其他详细信息。在 MapViewAnnotation 类中,您目前可能只有标题和坐标属性。您可以添加要与每个注释一起保留的附加信息(地址、电话号码、营业时间等),并在创建每个注释时设置此信息。有关此示例,请参阅 stackoverflow.com/questions/5939223/store-data-in-mkannotation
  • 很难从“仍然什么都没有”这句话中判断出问题所在。您能否提供更多详细信息,例如您看到的 NSLog、您执行了哪些步骤以及发生了什么或您看到了什么等?您是否在调试器中单步执行了代码并检查了每个方法是否被正确调用等?另请注意,您在调用 setZipString 时传递了 ann.title。对于 SO 问题,最好一次只关注一个小问题,如果该问题解决了就关闭它,然后针对下一个问题提出另一个问题。
【解决方案2】:

这很简单。您的内部循环负责将文本分配给标签。这两个循环遍历所有记录并不断将名称分配给 nameString 删除第一个记录的标签

self.nameString = nameString;

因此只存储最后一个字符串。

希望这会有所帮助。

谢谢, 库纳尔

【讨论】:

  • 那么您建议解决什么问题?
  • 请告诉我你到底想达到什么目标,只有我能帮你!
  • 我的详细信息页面上的标签(来自被按下的地图注释)仅显示我 plist 中的最后一项。但是,我所有的注释和标题都是正确的.. 都来自同一个 plist。无论按下什么注释。
  • 所以您只想显示正在按下的注释的名称.. 对吗?
  • 是的,最后是列表中的其他项目以及呼叫和方向按钮。但现在有点卡住了。
【解决方案3】:

看起来您实际上并没有为MapViewAnnotation 对象提供该位置的标签。

当您遍历 plist 中的数据时,标签上唯一发生的事情是将其设置为 self.nameString,这将不断被循环的每次迭代覆盖。

不确定您的代码到底想做什么,但看起来您对 name 值做得不够,无法实现您想要的。

【讨论】:

  • 他将标题(然后是注释标题)设置为与 nameString 相同的值,因此看起来他正确设置了图钉标题。
【解决方案4】:

当您遍历您的 plist 时,您需要一个数组来存储您的 namestring 而不是简单的 self.namestring NSString。

【讨论】:

  • 在这方面还是很新的......示例代码可以帮助我一点吗?
猜你喜欢
  • 1970-01-01
  • 2015-10-31
  • 1970-01-01
  • 2022-10-13
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
  • 2021-04-28
  • 2021-02-11
相关资源
最近更新 更多