【问题标题】:how to display data from plist in detail view using segue when map view annotation is pressed按下地图视图注释时如何使用segue在详细视图中显示plist中的数据
【发布时间】:2013-09-05 14:35:35
【问题描述】:

正如标题所描述的,我无法在我正在使用故事板中使用 segue 的地图视图项目中显示我的 plist 中的注释数据。我有地图视图,所有注释(图钉)都正确显示了它们的坐标。现在我想在用户按下详细信息披露按钮时使用 segue 转换到详细信息视图。到目前为止,我有以下内容是一个空的执行 segue:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
[self performSegueWithIdentifier:@"Details" sender:view];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
}

我想在详细视图中显示的详细信息被声明为字符串。如下

@interface ItalyMapDetail : UIViewController{
IBOutlet UIImageView *appImage;
IBOutlet UITextView *appText;
IBOutlet UILabel *appName;

NSString *appImageString;
NSString *appTextString;
NSString *appNameString;

}

@property (nonatomic, retain) NSString *appImageString;
@property (nonatomic, retain) NSString *appTextString;
@property (nonatomic, retain) NSString *appNameString;
@property (nonatomic, strong) UIImage* image;

@end

在.m文件中如下

@synthesize appImageString, appTextString, appNameString;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

appImage.image = [UIImage imageNamed:appImageString];
appText.text = appTextString;
appName.text = appNameString;
}

这是在细节视图中真正通用的一些字符串声明。 segue 标识符触发并且视图转换到详细视图并正确返回,因为我已经有一个导航控制器。现在我知道如何在 tableview 中声明字符串为 segue 做准备,但我不知道如何在 segue 中从我的 plist 中声明这些细节,以便在细节视图控制器中显示注释细节。谁能帮帮我。

哦,顺便说一下,如果有帮助,我认为我从 plist 派生的注释的声明确实加载了。

NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSString *path = [[NSBundle mainBundle] pathForResource:@"Map" ofType:@"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSArray *anns = [dict objectForKey:@"Italy"];

for(int i = 0; i < [anns count]; i++) {
    float realLatitude = [[[anns objectAtIndex:i] objectForKey:@"Latitude"] floatValue];
    float realLongitude = [[[anns objectAtIndex:i] objectForKey:@"Longitude"] floatValue];

    Annotation *myAnnotation = [[Annotation alloc] init];
    CLLocationCoordinate2D theCoordinate;
    theCoordinate.latitude = realLatitude;
    theCoordinate.longitude = realLongitude;
    myAnnotation.coordinate = theCoordinate;
    myAnnotation.title = [[anns objectAtIndex:i] objectForKey:@"Title"];
    myAnnotation.subtitle = [[anns objectAtIndex:i] objectForKey:@"Subtitle"];
    [myMapView addAnnotation:myAnnotation];
    [annotations addObject:myAnnotation];
}

我知道这对你们中的大多数人来说可能很容易,但我真的被困住了,我可以在代码级别使用一些帮助。

编辑 1:

这是建议更改后的代码:

    NSMutableArray *annotations = [[NSMutableArray alloc]init];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"ItalyMap" ofType:@"plist"];
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
    NSArray *anns = [dict objectForKey:@"Italy"];

    for(int i = 0; i < [anns count]; i++) {
    float realLatitude = [[[anns objectAtIndex:i] objectForKey:@"Latitude"] floatValue];
    float realLongitude = [[[anns objectAtIndex:i] objectForKey:@"Longitude"] floatValue];

    Annotation *myAnnotation = [[Annotation alloc] init];
    CLLocationCoordinate2D theCoordinate;
    theCoordinate.latitude = realLatitude;
    theCoordinate.longitude = realLongitude;
    myAnnotation.coordinate = theCoordinate;
    myAnnotation.title = [[anns objectAtIndex:i] objectForKey:@"Title"];
    myAnnotation.subtitle = [[anns objectAtIndex:i] objectForKey:@"Subtitle"];
    [myMapView addAnnotation:myAnnotation];
    [annotations addObject:myAnnotation];

    myAnnotation.annotationData = [anns objectAtIndex:i];
}

}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(@"view for annotation works");

if([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

static NSString *annotationIdentifier = @"AnnotationIdentifier";

MKPinAnnotationView *pinView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];

if (!pinView)
{
    pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];

    [pinView setPinColor:MKPinAnnotationColorGreen];
    pinView.animatesDrop = YES;
    pinView.canShowCallout = YES;

    UIImageView *iconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"acolon1.png"]];
    pinView.leftCalloutAccessoryView = iconView;

    pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
else
{
    pinView.annotation = annotation;
}

return pinView;
}

-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
// Keep a reference to the callout's annotation data
self.selectedAnnotationData = [(Annotation *)view.annotation annotationData];

[self performSegueWithIdentifier:@"Details" sender:self];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"Details"])
{
    ItalyMapDetail *controller = segue.destinationViewController;
    controller.annotationData = self.selectedAnnotationData;
}
}

现在我已将 dic 添加到注释并导入详细视图。唯一没有显示的是细节视图中的字符串和图像。

【问题讨论】:

    标签: ios objective-c mapkit mapkitannotation


    【解决方案1】:

    您可以将特定数据对象传递给Annotation 使用

    myAnnotation.annotationData = [anns objectAtIndex:i];
    

    然后在prepareForSegue:sender: 中,您可以访问注释数据并将其传递给详细视图控制器。


    编辑:添加示例代码

    在 Annotation 类上声明一个属性:

    @property (nonatomic, strong) NSDictionary *annotationData;
    

    在与地图视图相同的视图控制器上声明一个属性:

    @property (nonatomic, strong) NSDictionary *selectedAnnotationData;
    

    并实现地图视图委托方法:

    -(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
    calloutAccessoryControlTapped:(UIControl *)control
    {
        // Keep a reference to the callout's annotation data
        self.selectedAnnotationData = [(Annotation *)view.annotation annotationData];
    
        [self performSegueWithIdentifier:@"MY_SEGUE_IDENTIFIER" sender:self];
    }
    

    然后在prepareForSegue:sender:方法中将注解数据传递给后续控制器:

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([segue.identifier isEqualToString:@"showPlattegrondDetails"])
        {
            ItalyMapDetail *controller = segue.destinationViewController;
            controller.annotationData = self.selectedAnnotationData;
        }
    }
    

    修改 2:基于修改后的问题。

    在不知道 plist 中键的名称的情况下,我只能为您指出您应该寻找的方向。

    您的ItalyMapDetail 控制器应该具有前一个控制器的prepareForSegue:sender: 中提供的注释数据字典,它应该只是使用该字典中的值来填充您的 UI...

    如下更新ItalyMapDetail 控制器的viewDidLoad 方法:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        // temporary test: print out the annotation data so
        // we can see what we've got. This shouldn't be nil.
        NSLog("Annotation Data: %@", self.annotationData);
    
        // replace these keys with appropriate ones for your plist
        appImage.image = [UIImage imageNamed:self.annotationData[@"imageName"]];
        appText.text = self.annotationData[@"appText"];
        appName.text = self.annotationData[@"appName"];
    }
    

    【讨论】:

    • 你需要在 Annotation 类上声明一个名为 annotationData 的 NSDictionary @property。抱歉,我的示例中没有包含此内容:(
    • 我的答案的原始版本建议您将当前注释的整个字典传递到注释中。 myAnnotation.annotationData = [anns objectAtIndex:i];。这将在 for 循环中完成,您可以在其中设置每个注释,如问题中的最终代码 sn-p 所示。
    • 你能用你最近尝试的更多代码更新你的问题吗?我正在努力找出问题可能出在哪里。
    • 刚刚更新了包含您建议的代码的代码。
    • 史蒂夫,你帮了我很大的忙,谢谢你,谢谢你让我的脑袋免于爆炸。我不敢相信我错过了详细视图的整个结构。我很感谢您的帮助,而不仅仅是奖励正确的答案,我的朋友也为您的答案投票。非常感谢...:)
    猜你喜欢
    • 1970-01-01
    • 2014-10-04
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多