2012-05-02 11 views
2

私は、UITableViewControllerを含むPopoverViewコントローラを持つメインビュー(この場合はMKMapView)を持つiPadアプリケーションで作業しています。 UITableviewのコンテンツには、MapViewの注釈ピンを削除するために必要ないくつかの可変要素が含まれています。これらの変数は、選択された行に応じて変わります。私の考えはこれを達成するために代理人を使用することでしたが、私はそれを実装するのに苦労しています。デリゲートを使用してUIPopoverViewControllerとMainViewControllerの間で通信する

showIncidentListメソッドでデリゲートを宣言しました(同封のコードを参照)。私の質問は、このカスタムデリゲートがこの望ましい結果に適しているかどうかです。もしそうなら、私はデリゲートの情報を伝え、メインビューのplotCallLocationsメソッドをデリゲートの更新情報で呼び出すことができます。

Releventコード:

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

カスタムデリゲートのアプローチは、このような状況のための罰金です。

は、プロトコルで指定されている正確なメソッドであるincidentSelected:を実装していません。 (ちなみに、私は「TwitterSearchViewController」はミスであり、逆もまた同様で「SearchViewController」またはなければならないと仮定する。)

CallViewControllerもアレイを取る方法plotCallLocations:を有しているにもかかわらず、それは、正確と命名されていませんincidentSelected:(それが必要です)。

これについていくつかのコンパイラの警告が表示されるはずです。

したがって、SearchViewControllerがそのプロトコルメソッドを呼び出すと、「認識できないセレクタ」エラーでクラッシュする可能性があります。incidentSelected:

  • CallViewControllerにおいてplotCallLocations:に、incidentSelected:方法を追加し、plotCallLocations:プロトコルで
  • incidentSelected:に変更変更、CallViewController

    • :ここ

      は、いくつかの解決策(最初のものが最も容易である)でありますそこから電話するplotCallLocations:


    代理人がnilかどうかを確認する代わりに、SearchViewControllerに代わって、代理人がrespondsToSelector:を使用して実際に呼び出す方法を持っているかどうかを確認することをお勧めします。代わりに、デリゲートがnilであるかどうかをチェックするの、SearchViewControllerで今

    @protocol IncidentPickerDelegate<NSObject> 
    

    :最初のあなたはIncidentPickerDelegateNSObjectプロトコルを実装するために必要があります。これを行うには、

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

    不思議なことに、ときメソッド名とデリゲート名が異なっていました。私はコンパイラの警告やエラーを受け取っていませんでした。私はあなたの提案された変更を反映するために上記と私のコードを更新しました。 incidentSelectedメソッドを実行するにはこれまでのところ運がありません。コードにアクセスするかどうかをテストするNSLogがあります。ご協力いただきありがとうございます! – blueHula

    +0

    didSelectRowAtIndexPathにブレークポイントまたはNSLogを置き、コードが期待どおりに実行されていることを確認します。 "respondsToSelector"条件を満たしているかどうかを確認します。 – Anna

    +0

    そうです。 respondsToSelector条件を渡したばかりの出力をログに記録し、NSMutableArrayの内容がコンソールに記録されました。 – blueHula

    関連する問題