我已经按照几个教程/示例/答案等来尝试在popoverController中使用“取消”按钮,使用委托方法来关闭弹出窗口(本身)。我没有运气而且我被困住了。以下是相关的代码片段。
我知道cancelButtonPushed方法被成功调用,但我的黄金方法“didClickCancelButton”永远不会被调用。
任何见解?
这是我有的:
//
// 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
这是创建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
我应该抓住这个。我需要在viewController上设置委托,而不是我的popoverController。
_practiceAreasFilterViewController.delegate = self;
代替
_practiceAreasPopoverController.delegate = self;
尝试用initialize
替换init
。
当Objective-C启动你的程序时调用+(void) initialize
方法,并为每个类调用它。 (见here)。
这不是初始化新对象时调用的方法,即init
(或其任何变体,`initWith ...)。所以,这应该解释为什么没有设置委托。