Получение XML-данных в DetailView из вида карты (Iphone IOS) - PullRequest
1 голос
/ 18 марта 2011

Мы пытаемся создать вид карты с аннотациями, загруженными из XML-файла. Это работает до сих пор и использует код KMLViewer в библиотеке разработчика Apple. Теперь мы пытаемся загрузить данные из файла XML в подробный вид, но только соответствующую запись. Поэтому, когда вы нажимаете, например, информацию о городе, информация должна быть загружена из файла XML этого города.

Мы пытаемся уже несколько дней, но просто не знаем, с чего начать. Теперь у нас есть следующий код:

detailviewcontroller.m

    #import "DetailViewController.h"



@implementation DetailViewController

@synthesize address;




// Implement viewDidLoad to do additional setup after loading the view, typically from a nib
- (void)viewDidLoad
{
    TabbedCalculationAppDelegate *appDelegate = (TabbedCalculationAppDelegate *)[[UIApplication sharedApplication] delegate];
    address.text = appDelegate.addressInput1 ;

    [super viewDidLoad];
}

- (void)viewDidUnload
{
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)dealloc
{
    [super dealloc];
}

Просмотр карты

#import "locator.h"
#import "DetailViewController.h"

@implementation locator

@synthesize map, detailViewController, rightButton, customPinView;


- (void)viewDidLoad
{
    [super viewDidLoad];

    // create a custom navigation bar button and set it to always says "Back"
    UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init];
    temporaryBarButtonItem.title = @"Back";
    self.navigationItem.backBarButtonItem = temporaryBarButtonItem;
    [temporaryBarButtonItem release];

    // Locate the path to the route.kml file in the application's bundle
    // and parse it with the KMLParser.
    NSString *path = [[NSBundle mainBundle] pathForResource:@"branches" ofType:@"kml"];
    kml = [[KMLParser parseKMLAtPath:path] retain];

    // Add all of the MKOverlay objects parsed from the KML file to the map.
    NSArray *overlays = [kml overlays];
    [map addOverlays:overlays];

    // Add all of the MKAnnotation objects parsed from the KML file to the map.
    NSArray *annotations = [kml points];

    [map addAnnotations:annotations];

    // Walk the list of overlays and annotations and create a MKMapRect that
    // bounds all of them and store it into flyTo.
    MKMapRect flyTo = MKMapRectNull;
    for (id <MKOverlay> overlay in overlays) {
        if (MKMapRectIsNull(flyTo)) {
            flyTo = [overlay boundingMapRect];
        } else {
            flyTo = MKMapRectUnion(flyTo, [overlay boundingMapRect]);
        }
    }

    for (id <MKAnnotation> annotation in annotations) {
        MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
        MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
        if (MKMapRectIsNull(flyTo)) {
            flyTo = pointRect;
        } else {
            flyTo = MKMapRectUnion(flyTo, pointRect);
        }
    }

    // Position the map so that all overlays and annotations are visible on screen.
    MKCoordinateRegion mapRegion;
    mapRegion.center.latitude = 51.522416;
    mapRegion.center.longitude = 5.141602;
    mapRegion.span.latitudeDelta = 5;
    mapRegion.span.longitudeDelta = 5;
    [map setRegion:mapRegion animated:YES];
}


#pragma mark MKMapViewDelegate

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
    return [kml viewForOverlay:overlay];
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    // if it's the user location, just return nil.
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    // handle custom annotations
    //        // try to dequeue an existing pin view first
    static NSString* BridgeAnnotationIdentifier = @"bridgeAnnotationIdentifier";
    MKPinAnnotationView* pinView = (MKPinAnnotationView *)
    [map dequeueReusableAnnotationViewWithIdentifier:BridgeAnnotationIdentifier];

    if (!pinView)
    {
        // if an existing pin view was not available, create one
        customPinView = [[[MKPinAnnotationView alloc]
                                               initWithAnnotation:annotation reuseIdentifier:BridgeAnnotationIdentifier] autorelease];
        customPinView.pinColor = MKPinAnnotationColorPurple;
        customPinView.animatesDrop = YES;
        customPinView.canShowCallout = YES;

        // add a detail disclosure button to the callout which will open a new view controller page
        //
        // note: you can assign a specific call out accessory view, or as MKMapViewDelegate you can implement:
        //  - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
        //
        rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        customPinView.rightCalloutAccessoryView = rightButton;

        return customPinView;
    }else{
        return pinView;}

    return nil;

}

#pragma mark -
#pragma mark MKMapViewDelegate

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    {
        if (view.annotation == mapView.userLocation)
            return;

        rightButton = (DetailViewController *)view.annotation;        
        //show detail view using buttonDetail...
    }
    // the detail view does not want a toolbar so hide it
    [self.navigationController setToolbarHidden:YES animated:YES];


    [self.navigationController pushViewController:self.detailViewController animated:YES];
}

- (void)viewDidUnload
{
    self.detailViewController = nil;

}

- (void)dealloc 
{
    [detailViewController release];
    [super dealloc];
}

@end

Как вы можете видеть, код начинает выглядеть грязно после множества попыток, но мы не знаем, с чего начать.

Любая помощь будет чрезвычайно признательна

Спасибо заранее!

1 Ответ

2 голосов
/ 23 марта 2011

Пожалуйста, посмотрите на интерфейс KMLPlacemark в KMLParser, там вы можете увидеть, что именно анализируется и хранится в элементе метки xml. Например, адрес отсутствует. Поэтому вам нужно будет добавить всю информацию, которую вы хотите, чтобы анализатор собирал, реализовав поля в классе KMLPlacemark и изменив методы KMLParser:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName ...
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName ...

, а также некоторые части реализации KMLPlacemark. Чтобы заполнить новые поля парсером, вам нужно написать такие методы, как - (void)beginName и - (void)endName. Будет немного сложно, если у элементов, которые вы хотите проанализировать, есть дети.

Может быть полезно разделить файл KMLParser на несколько файлов, каждый из которых содержит один класс.

Если вы достигли этого, и ваша метка содержит все необходимые данные, вы можете заметить, что нажмите на аннотацию с протоколом MKMapViewDelegate. Реализуйте didDeselectAnnotationView , который может выглядеть следующим образом:

- (void) mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
    // implementation example of placemarkForAnnotation below
    KMLPlacemark * placemark = [kml placemarkForAnnotation:view.annotation];

    MyDetailViewController * myDetailViewController = [[MyDetailViewController alloc] initWithPlacemark:placemark];

    [self presentModalViewController:myDetailViewController animated:YES];

    [myDetailViewController release];
}

В KMLParser добавить

- (KMLPlacemark *)placemarkForAnnotation:(id <MKAnnotation>)point
{
    // Find the KMLPlacemark object that owns this point and return it
    for (KMLPlacemark *placemark in _placemarks) {
        if ([placemark point] == point)
            return placemark;
    }
    return nil;
}

Надеюсь, я мог бы указать вам правильное направление. Это будет какая-то работа;)

...