2012-05-02 37 views
2

我正在使用包含UITableViewController的PopoverView控制器的iPad应用程序,该应用程序具有主视图(在本例中为MKMapView)。 UITableview中的内容包含许多可变元素,我需要在MapView上放置注释引脚。这些变量取决于选择哪一行。我的想法是使用委托来实现这一点,但我正在努力实现它。使用委托在UIPopoverViewController和MainViewController之间进行通信

我已经在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 

SearchViewController.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; 

CallViewController.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]; 

} 

回答

1

的自定义委托的办法是罚款这种情况。

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

即使CallViewController具有方法plotCallLocations:这也需要一个数组,它未命名恰好 (它需要是)。

你应该得到一些关于这个的编译器警告。

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

这里有一些解决方案(第一种是最简单的):

  • CallViewController,更改plotCallLocations:incidentSelected:
  • 在该协议中,更改incidentSelected:plotCallLocations:
  • CallViewController,添加一个incidentSelected:方法并从那里拨打plotCallLocations:


单独地(不是引起问题,但是)在SearchViewController中,而不是检查代理是否为nil,最好检查代理实际上是否有使用respondsToSelector:来调用的方法。

要做到这一点,首先你必须做出IncidentPickerDelegate实现NSObject协议:

@protocol IncidentPickerDelegate<NSObject> 

现在SearchViewController,而不是检查,如果委托是nil:当

if ([_delegate respondsToSelector:@selector(incidentSelected:)]) 
+0

奇怪的是,方法名称和委托名称是不同的我没有得到任何编译器警告或错误。我更新了我的代码和上面的内容以反映您的建议更改。到目前为止,没有运气让事件选择的方法运行。注意我有一个NSLog来测试代码是否被访问过,而不是。谢谢你的帮助! – blueHula

+0

在didSelectRowAtIndexPath中放置断点或NSLog,并确保代码按预期运行。检查它是否通过了“respondsToSelector”条件。 – Anna

+0

它似乎。我记录了刚刚传递了res​​pondsToSelector条件的输出,并且在控制台中记录了NSMutableArray内容。 – blueHula

相关问题