2

我正在开发一个 iPad 应用程序,该应用程序具有一个主视图(在本例中为 MKMapView)和一个包含 UITableViewController 的 PopoverView 控制器。UITableview 中的内容包含许多变量元素,我需要这些元素在 MapView 上放置注释引脚。这些变量会根据选择的行而变化。我的想法是使用委托来完成此任务,但我正在努力实现它。

我已经在 showIncidentList 方法中声明了委托(参见随附的代码)。我的问题是,这个自定义委托是否适合这个期望的结果,如果是这样,我缺少什么可以让我在委托中传达信息并使用来自委托的更新信息调用主视图上的 plotCallLocations 方法。

相关代码:

SearchViewController.h //popoverViewController 类

@protocol IncidentPickerDelegate <NSObject>

- (void)incidentSelected:(NSMutableArray *)incidentDetail;

@end

@interface SearchViewController : UITableViewController  <UITableViewDelegate, UITableViewDataSource> { 
__weak id<IncidentPickerDelegate> _delegate;
}

@property (nonatomic, retain) NSMutableArray *incidentDetails;
@property (nonatomic, weak) id<IncidentPickerDelegate> delegate;
@end

搜索视图控制器.m

#import "TwitterSearchViewController.h"
#import "CallViewController.h"

@implementation SearchViewController

@synthesize delegate = _delegate;
@synthesize incidentDetails= _incidentDetails;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

_incidentDetails = [[NSMutableArray alloc] initWithObjects:[textItems objectAtIndex:0], [textItems objectAtIndex:1], lat, lon, nil];     //textItems is an NSArray of parsed JSON data, lat and lon are int's

 NSLog(@"_delegate = %@", _delegate);
        if ([_delegate respondsToSelector:@selector(incidentSelected:)]) {
            NSMutableArray *incidentDet = _incidentDetails;
            [_delegate incidentSelected:incidentDet];
 NSLog(@"incidentDetail ----> %@", incidentDet);
} 

@end

CallViewController.h //MainViewController

#import "SearchViewController.h"

@interface CallViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate, UIAlertViewDelegate, IncidentPickerDelegate> {
}

@property (nonatomic, retain) UIPopoverController *incidnetListPopover;
@property (nonatomic, retain) SearchViewController *incidentPicker;

-(IBAction)showIncidentList:(id)sender;

调用视图控制器.m

#import "CallViewController.h"
#import "SearchViewController.h"

@implementation CallViewController

@synthesize incidnetListPopover = _incidnetListPopover;
@synthesize incidentPicker = _incidentPicker;

UIStoryboard*  sb = [UIStoryboard storyboardWithName:@"MainStoryboard"
                                              bundle:nil];

if (_incidentPicker == nil) {
    self.incidentPicker = [sb instantiateViewControllerWithIdentifier:@"SearchViewController"];
    _incidentPicker.delegate = self;

    self.incidnetListPopover = [[UIPopoverController alloc] 
                                initWithContentViewController:_incidentPicker];               
}

[self.incidnetListPopover presentPopoverFromBarButtonItem:sender 
                                permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

}


- (void)incidentSelected:(NSMutableArray *)incidentDetail {


//    for (id<MKAnnotation> annotation in _mapView.annotations) {
//      [_mapView removeAnnotation:annotation];

NSLog(@"plotCall called");
NSNumber * latitude = [incidentDetail objectAtIndex:2];
NSNumber * longitude = [incidentDetail objectAtIndex:3];
NSString * name = [incidentDetail objectAtIndex:1];
NSString * address = [incidentDetail objectAtIndex:0];
CLLocationCoordinate2D coordinate;
coordinate.latitude = latitude.doubleValue;
coordinate.longitude = longitude.doubleValue;  

CallLocation *annotation = [[CallLocation alloc] initWithName:name address:address coordinate:coordinate];
[_mapView addAnnotation:annotation];  

[self.incidnetListPopover dismissPopoverAnimated:YES];

}
4

1 回答 1

1

自定义委托方法适用于这种情况。

主要问题是CallViewController没有实现IncidentPickerDelegate协议中指定的确切方法,即incidentSelected:. (顺便说一句,我假设“TwitterSearchViewController”是一个错字,应该是“SearchViewController”,反之亦然。)

即使CallViewControllerplotCallLocations:也采用数组的方法,但它的名称并不准确 incidentSelected:(它必须是)。

您应该会收到一些关于此的编译器警告。

因此,当SearchViewController调用该协议方法时,它可能会因“无法识别的选择器”错误而崩溃。

以下是一些解决方案(第一个是最简单的):

  • CallViewController,更改plotCallLocations:incidentSelected:
  • 在协议中,更改incidentSelected:plotCallLocations:
  • CallViewController中,添加一个incidentSelected:方法,然后从那里调用plotCallLocations:


另外(不会引起问题,但是),在 中SearchViewController,而不是检查委托是否是nil,最好检查委托是否确实具有您将要使用的方法调用的方法respondsToSelector:

为此,首先您必须IncidentPickerDelegate实现NSObject协议:

@protocol IncidentPickerDelegate<NSObject>

现在在SearchViewController,而不是检查委托是否是nil

if ([_delegate respondsToSelector:@selector(incidentSelected:)])
于 2012-05-02T22:17:02.617 回答