1

我在开发应用程序时遇到问题:我的应用程序显示了一张图片,我在这张图片上得到了一些分数。我在 XML 文件中找到点,所以我在 2 个视图控制器中做了:第一个显示图像视图和导航栏以通过 segue 调用第二个视图控制器,在第二个视图控制器中我解析 XML 文件获取我将在图像中找到的地点的名称和坐标(以像素为单位)。我的问题是它从未初始化过的委托,所以我问你是否可以帮助我解决这个问题。我希望你能帮助我找到一个正确的方法来完成这个应用程序。我在这里发布我的代码。

视图控制器.h

 #import <UIKit/UIKit.h>
#import "PlacesViewController.h"

@interface ViewController : UIViewController <UIScrollViewDelegate, UITextFieldDelegate, PlacesDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *viewScroll;
@property (weak, nonatomic) IBOutlet UIImageView *viewImage;
@property (nonatomic, strong) PlacesViewController *placesViewController;

- (IBAction)drawPinToMap:(id)sender;

@end

视图控制器.m

#import "ViewController.h"
#import "PlacesViewController.h"

@interface ViewController ()

@property CGSize imageSize;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.imageSize = self.viewImage.image.size;
    [self.viewScroll setContentSize:self.imageSize];
    [self.viewScroll setDelegate:self];

}


- (void)viewWillAppear:(BOOL)animated
{
    CGPoint svOrig = self.viewScroll.frame.origin;
    [self.viewImage setFrame:CGRectMake(svOrig.x, svOrig.y, self.imageSize.width, self.imageSize.height)];
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated {
    [self.viewImage setTag:100];
    float minimunScale = 1;
    float maximumScale = 4;
    float startZoomScale = 1;

    [self.viewScroll setMinimumZoomScale:minimunScale];
    [self.viewScroll setMaximumZoomScale:maximumScale];
    [self.viewScroll setZoomScale:startZoomScale];
}

- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return [self.viewScroll viewWithTag:100];
}

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

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    [self.placesViewController setDelegate:self];
}

//Method to test if the code can draw the pin in the middle point of the image
- (IBAction)drawPinToMap:(id)sender {
    CGRect svframe = self.viewScroll.bounds;
    [self.viewScroll setContentOffset:CGPointMake(self.imageSize.width / 2. - svframe.size.width / 2., self.imageSize.height / 2. - svframe.size.height / 2.) animated:YES];
    UIImageView *pin = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pin"]];
    [self.viewScroll addSubview:pin];
    [pin setFrame:CGRectMake(0, 0, 21, 44)];
    CGRect pinFrame = pin.frame;
    pinFrame.origin.x = self.imageSize.width / 2.;
    pinFrame.origin.y = self.imageSize.height / 2.;
    pin.frame = pinFrame;
}

//Delegate method
- (void) drawPinToMapForCity:(NSString *)city andPosX:(NSNumber *)posX andPosY:(NSNumber *)posY {
    NSLog(@"City: %@ posX = %@ posY = %@", city, posX, posY);
}
@end

PlacesViewController.h

#import <UIKit/UIKit.h>

@protocol PlacesDelegate;

@interface PlacesViewController : UITableViewController <NSXMLParserDelegate>

@property (assign) id <PlacesDelegate> delegate;

@end

@protocol PlacesDelegate <NSObject>

- (void) drawPinToMapForCity:(NSString*)city andPosX:(NSNumber*)posX andPosY:(NSNumber*)posY;

@end

PlacesViewController.m

#import "PlacesViewController.h"

@interface PlacesViewController () {
    NSXMLParser *placesXmlParser;
}
@property (nonatomic, strong) NSMutableArray *arrayPlaces;

- (void) parseXmlFileAtUrl:(NSString *)URL;

@end

@implementation PlacesViewController

@synthesize delegate = _delegate;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.arrayPlaces = [[NSMutableArray alloc] init];
    NSString *pathXmlFile = [[NSBundle mainBundle] pathForResource:@"places" ofType:@"xml"];
    [self parseXmlFileAtUrl:pathXmlFile];
}

- (void) parseXmlFileAtUrl:(NSString *)URL {
    //Creazione dell'URL
    NSURL *xmlUrl = [NSURL URLWithString:URL];
    NSString *host = [xmlUrl host];
    if (xmlUrl == nil || host == nil) {
        NSData *data = [[NSData alloc] initWithContentsOfFile:URL];
        placesXmlParser = [[NSXMLParser alloc] initWithData:data];
    }
    else {
        placesXmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlUrl];
    }
    [placesXmlParser setDelegate:self];
    [placesXmlParser setShouldProcessNamespaces:NO];
    [placesXmlParser setShouldReportNamespacePrefixes:NO];
    [placesXmlParser setShouldResolveExternalEntities:NO];
    [placesXmlParser parse];
}

- (void)parserDidStartDocument:(NSXMLParser *)parser {
    NSLog(@"File trovato inizio il parsing del documento");
}


- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    NSLog(@"Errore Parsing");
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
    if ([elementName isEqualToString:@"places"]) {
    } else if ([elementName isEqualToString:@"place"]) {
        NSString *cityValue = attributeDict[@"name"];
        NSString *posXValue = attributeDict[@"posX"];
        NSString *posYValue = attributeDict[@"posY"];

        NSDictionary* place = @{@"name": cityValue,
                                @"posX": posXValue,
                                @"posY": posYValue};
        [self.arrayPlaces addObject:place];
        NSLog(@"arraPlaces dim = %d", self.arrayPlaces.count);
    }
}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
}


- (void)parserDidEndDocument:(NSXMLParser *)parser {
    NSLog(@"ArrayPlaces = %@", self.arrayPlaces);
}

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

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [self.arrayPlaces count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.textLabel.text = [self.arrayPlaces[indexPath.row] objectForKey:@"name"];

    return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     self.arrayPlaces[indexPath.row]objectForKey:@"posX"]
     [self.navigationController pushViewController:detailViewController animated:YES];
     */
//I put here a NSLog to see if my delegate has a value, but if i run the app it says null and my app doesn't work properly
    NSLog(@"%@", self.delegate);
    [_delegate drawPinToMapForCity:[self.arrayPlaces[indexPath.row]objectForKey:@"name"] andPosX:[self.arrayPlaces[indexPath.row]objectForKey:@"posX"] andPosY:[self.arrayPlaces[indexPath.row]objectForKey:@"posY"]];
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end

如果我运行应用程序,我会在控制台中看到:

2013-04-12 14:49:24.770 MiddleEarth[3346:c07] ArrayPlaces = (
    {
    name = "name1";
    posX = coordX;
    posY = coordY;
},
    {
    name = "name2";
    posX = coordX;
    posY = coordY;
}

)

2013-04-12 14:49:26.171 MiddleEarth[3346:c07] DELEGATE VALUE: (null)

在最后一行中,您可以看到我的委托没有值,因此我无法将变量提供给 ViewController,我可以使用它在图像上绘制图钉。我将 XML 解析器放在 PlacesViewController 中,这是我的选择。我希望你能帮助我找出我做错了什么。

4

2 回答 2

3

您需要在中设置委托属性prepareForSegue:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"some-segue-name"]) {
        PlacesViewController *vc = [segue destinationViewController];

        // set the delegate to a ViewController reference
        vc.delegate = self;
    }
}
于 2013-04-12T12:53:41.607 回答
0

self.placesViewController不是将在 Storyboard 中推送的 ViewController!

试试这个:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"yourSegueName"]) {
        [(PlacesViewController*)[segue destinationViewController] setDelegate:self];
    } 
}
于 2013-04-12T12:58:24.043 回答