iOS UIPopoverController delegate not working, remains nil
I have followed several tutorials/examples/answers, etc., to try and have a Cancel button within a popoverController use the delegate method to dismiss the popover (itself). I have had no luck and I'm stuck. Below are the p开发者_开发技巧ertinent code snippets.
I know the cancelButtonPushed method is being called successfully, but my golden method "didClickCancelButton" is never being called.
Any insight?
Here is what I have:
//
// MIPracticeAreasFilterViewController.h
//
#import <UIKit/UIKit.h>
@protocol MyPopoverDelegate
-(void)didClickCancelButton;
@end
@interface MIPracticeAreasFilterViewController : UITableViewController {
//other vars
id <MyPopoverDelegate> delegate;
}
//other properties
@property (nonatomic, assign) id <MyPopoverDelegate> delegate;
//other methods
-(IBAction)cancelButtonPush:(id)sender;
@end
//
// MIPracticeAreasFilterViewController.m
//
#import "MIPracticeAreasFilterViewController.h"
@interface MIPracticeAreasFilterViewController()
-(UITableViewCell *)buttonCellForTableView:(UITableView*)tableView;
-(UITableViewCell *)submitOrCancelCellForTableView:(UITableView*)tableView;
@end
@implementation MIPracticeAreasFilterViewController
@synthesize practiceAreas=_practiceAreas;
@synthesize selectedPracticeAreas=_selectedPracticeAreas;
@synthesize delegate;
- (id)initWithStyle:(UITableViewStyle)style
{
//init stuff
}
- (void)dealloc
{
}
- (void)didReceiveMemoryWarning
{
}
-(IBAction)cancelButtonPush:(id)sender
{
if (self.delegate == nil)
{
NSLog(@"Delegate is nil. Cancel button pushed.");
}
//[[self delegate] didClickCancelButton];
[self.delegate didClickCancelButton];
}
- (UITableViewCell *)submitOrCancelCellForTableView:(UITableView *)tableView
{
static NSString *CellIdentifier = @"PracticeAreaSubmitOrCancelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSUInteger buttonSpace = 10;
NSUInteger buttonWidth = 120;
NSUInteger buttonHeight = 34;
NSUInteger buttonStartX = 80;
NSUInteger buttonY = 4;
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cancelButton addTarget:self action:@selector(cancelButtonPush:) forControlEvents:UIControlEventTouchUpInside];
cancelButton.frame = CGRectMake(buttonStartX + buttonWidth*1 + buttonSpace*1, buttonY, buttonWidth, buttonHeight);
[cancelButton setTitle:@"Cancel" forState:UIControlStateNormal];
[cell.contentView addSubview:cancelButton];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
//clicked the "select" cell, all the handlers are their responsibility.
return;
}
if (indexPath.row == 1) {
//clicked the "submit or cancel" cell, all the handlers are their responsibility.
return;
}
NSString *practiceArea = [_practiceAreas objectAtIndex:indexPath.row-2];
if ([_selectedPracticeAreas containsObject:practiceArea]) {
//remove the object
[_selectedPracticeAreas removeObject:practiceArea];
} else {
[_selectedPracticeAreas addObject:practiceArea];
}
[tableView reloadData];
}
@end
And here is the view controller that creates the popoverController:
//
// MIRootViewController.h
//
#import <UIKit/UIKit.h>
#import "MILandingPageViewController.h"
#import "MIPracticeAreasFilterViewController.h"
#import "MILoginViewController.h"
@interface MIRootViewController : UIViewController <UIPopoverControllerDelegate, UITextFieldDelegate, MILoginCompleteDelegate, MIInterfaceOrientationDelegate, UINavigationControllerDelegate, MyPopoverDelegate>
{
//other objects
UIPopoverController *_practiceAreasPopoverController;
MIPracticeAreasFilterViewController *_practiceAreasFilterViewController;
}
//other properties
@property (nonatomic, readwrite, retain) UIPopoverController *practiceAreasPopoverController;
@property (nonatomic, readwrite, retain) MIPracticeAreasFilterViewController *practiceAreasFilterViewController;
//other methods
- (void) didClickCancelButton;
@end
//
// MIRootViewController.m
//
#import "MIRootViewController.h"
#import "HLReachability.h"
#import "MILoginStatusManager.h"
#import "MITextInsightDataUpdater.h"
@interface MIRootViewController ()
//other methods
- (void)didClickCancelButton;
@end
@implementation MIRootViewController
@synthesize practiceAreasPopoverController = _practiceAreasPopoverController;
@synthesize practiceAreasFilterViewController = _practiceAreasFilterViewController;
- (void)dealloc
{
//stuff
[super dealloc];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
[self initialize];
}
return self;
}
- (void)initialize
{
[[MIAppModel sharedInstance] preloadImages];
_practiceAreasFilterViewController = [[MIPracticeAreasFilterViewController alloc] initWithStyle:UITableViewStylePlain];
_practiceAreasPopoverController = [[UIPopoverController alloc] initWithContentViewController:_practiceAreasFilterViewController];
_practiceAreasPopoverController.popoverContentSize = CGSizeMake(400, 900);
_practiceAreasPopoverController.delegate = self;
}
#pragma mark MyPopover delegate
-(void)didClickCancelButton
{
NSLog(@"Success! Clicked Cancel from ROOT VIEW");
if ([_practiceAreasPopoverController isPopoverVisible])
{
[_practiceAreasPopoverController dismissPopoverAnimated:YES];
[_practiceAreasPopoverController release];
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
//bring back the popover if it was visible before the rotation
if (_practiceAreasPopoverControllerWasVisible)
{
CGRect popoverFrame = _practiceAreasButton.superview.frame;
popoverFrame.origin.x += _practiceAreasButton.frame.origin.x;
popoverFrame.origin.y += _practiceAreasButton.frame.origin.y;
popoverFrame.size = _practiceAreasButton.frame.size;
popoverFrame.size.height = _practiceAreasButton.frame.size.height;
[_practiceAreasPopoverController presentPopoverFromRect:popoverFrame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:NO];
}
[_navController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
_practiceAreasPopoverControllerWasVisible = [_practiceAreasPopoverController isPopoverVisible];
if (_practiceAreasPopoverControllerWasVisible) {
//hide it before the rotation
[_practiceAreasPopoverController dismissPopoverAnimated:NO];
}
[_navController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
#pragma mark - Actions
- (IBAction) practiceAreasTouch:(id)sender
{
[_searchInput resignFirstResponder];
[_practiceAreasPopoverController setDelegate:self];
if (![_practiceAreasPopoverController isPopoverVisible]) {
//show the popover
CGRect popoverFrame = _practiceAreasButton.superview.frame;
popoverFrame.origin.x += _practiceAreasButton.frame.origin.x;
popoverFrame.origin.y += _practiceAreasButton.frame.origin.y;
popoverFrame.size = _practiceAreasButton.frame.size;
popoverFrame.size.height = _practiceAreasButton.frame.size.height;
[_practiceAreasPopoverController presentPopoverFromRect:popoverFrame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
else
{
[_practiceAreasPopoverController dismissPopoverAnimated:NO];
}
}
#pragma mark - Practice Areas Filter PopoverControllerDelegate
- (void) popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
if ([_searchInput.text isEqualToString:@""]) {
//just use the insights
_landingPageController.textInsights = [[MIAppModel sharedInstance] textInsightsForTopics:_practiceAreasFilterViewController.selectedTopics ];
}
else
{
//filter by search as well
_landingPageController.textInsights = [[MIAppModel sharedInstance] textInsightsForTopics:_practiceAreasFilterViewController.selectedTopics matchingSearch:_searchInput.text ];
}
[self showBackButtonAnimated:YES];
_filterOn = YES;
[_landingPageController.layoutView reloadDataWithInterfaceOrientation:self.interfaceOrientation];
}
@end
I should have caught this. I needed to set the delegate on my viewController, not my popoverController.
_practiceAreasFilterViewController.delegate = self;
instead of
_practiceAreasPopoverController.delegate = self;
Try to replace initialize
with init
.
The +(void) initialize
method is called when Objective-C starts your program, and it's called for every class. (see here).
This is not the method that will be called when you initialize a new object, that is init
(or any variant of it, `initWith...). So, that should explain why the delegate is not set.
精彩评论