2

UITableViewController を含む PopoverView コントローラーを備えたメイン ビュー (この場合は MKMapView) を持つ iPad アプリで作業しています。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

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

}
4

1 に答える 1

1

この状況では、カスタム デリゲート アプローチが適しています。

主な問題は、であるプロトコルでCallViewController指定された正確なメソッドを実装していないことです。 (ちなみに、「TwitterSearchViewController」はタイプミスであり、「SearchViewController」またはその逆である必要があると思います。)IncidentPickerDelegateincidentSelected:

配列も取るCallViewControllerメソッドがありますが、正確に名前が付けられていません(そうである必要があります)。plotCallLocations: 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 に答える