UIViewController 可能不响应 showRootPopoverButtonItem
Posted
技术标签:
【中文标题】UIViewController 可能不响应 showRootPopoverButtonItem【英文标题】:UIViewController may not respond to showRootPopoverButtonItem 【发布时间】:2012-02-08 21:47:48 【问题描述】:我正在使用 Apple 的 MuiltipleDetailViewController 示例应用程序并收到消息“UIViewController 可能无法响应 showRootPopoverButtonItem”
这在 XCode 3.X 中有效,但我收到了 4.2 的消息
应用程序本身功能 100%,每个笔尖都能识别弹出框,横向模式下左侧的表格也是如此。但我不能提交这个警告。我需要改变什么?
RootViewController.h
#import <UIKit/UIKit.h>
/*
SubstitutableDetailViewController defines the protocol that detail view controllers must adopt. The protocol specifies methods to hide and show the bar button item controlling the popover.
*/
@protocol SubstitutableDetailViewController <NSObject>
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
@end
@interface RootViewController : UITableViewController <UISplitViewControllerDelegate>
UISplitViewController *splitViewController;
UIPopoverController *popoverController;
UIBarButtonItem *rootPopoverButtonItem;
//UINavigationBar *navigationBar;
@property (nonatomic, assign) IBOutlet UISplitViewController *splitViewController;
@property (nonatomic, retain) UIPopoverController *popoverController;
@property (nonatomic, retain) UIBarButtonItem *rootPopoverButtonItem;
//@property (nonatomic, retain) IBOutlet UINavigationBar *navigationBar;
@end
RootViewController.m:
#import "RootViewController.h"
#import "WebViewController.h"
#import "Twitter.h"
//#import "SubstitutableDetailViewController.h"
@implementation RootViewController
@synthesize splitViewController, popoverController, rootPopoverButtonItem;//, navigationBar;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad
[super viewDidLoad];
// Set the content size for the popover: there are just two rows in the table view, so set to rowHeight*2.
self.contentSizeForViewInPopover = CGSizeMake(310.0, self.tableView.rowHeight*2.0);
//self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:255/255 green:104/255 blue:1/255 alpha:1];
/*
-(void)customizeAppearance
//create resizable images
UIImage *bluImage = [UIImage imageNamed:@"blu.jpg"];// resizableImageWithCapInsets:(0, 0, 0, 0)];
//set the bg for *all* UINavBars
[[UINavigationBar appearance] setBackgroundImage:bluImage forBarMetrics:UIBarMetricsDefault];
*/
-(void) viewDidUnload
[super viewDidUnload];
self.splitViewController = nil;
self.rootPopoverButtonItem = nil;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return YES;
- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem
forPopoverController:(UIPopoverController*)pc
// Keep references to the popover controller and the popover button, and tell the detail view controller to show the button.
barButtonItem.title = @"Index";
self.popoverController = pc;
self.rootPopoverButtonItem = barButtonItem;
UIViewController <SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController showRootPopoverButtonItem:rootPopoverButtonItem];
- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
// Nil out references to the popover controller and the popover button, and tell the detail view controller to hide the button.
UIViewController <SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController invalidateRootPopoverButtonItem:rootPopoverButtonItem];
self.popoverController = nil;
self.rootPopoverButtonItem = nil;
#pragma mark -
#pragma mark Table view data source
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section
// Two sections, one for each detail view controller.
return 2;
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"RootViewControllerCellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
//cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
// Set appropriate labels for the cells.
if (indexPath.row == 0)
cell.textLabel.text = @"Twitter";
else if (indexPath.row == 1)
cell.textLabel.text = @"Contact Us";
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.backgroundColor = [UIColor blackColor];
cell.contentView.backgroundColor = [UIColor blackColor];
cell.detailTextLabel.backgroundColor = [UIColor blackColor];
return cell;
#pragma mark -
#pragma mark Table view selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
/*
Create and configure a new detail view controller appropriate for the selection.
*/
NSUInteger row = indexPath.row;
UIViewController *detailViewController = nil;
if (row == 0)
Twitter *newDetailViewController = [[Twitter alloc]
initWithNibName:@"Twitter"
bundle:nil];
detailViewController = newDetailViewController;
if (row == 1)
WebViewController *newDetailViewController = [[WebViewController alloc]
initWithNibName:@"WebViewController"
bundle:nil];
newDetailViewController.detailURL=
[[NSURL alloc] initWithString:@"http://www.chipmunkmobile.com/contact.html"];
detailViewController = newDetailViewController;
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
[viewControllers release];
// Dismiss the popover if it's present.
if (popoverController != nil)
[popoverController dismissPopoverAnimated:YES];
// Configure the new view controller's popover button (after the view has been displayed and its toolbar/navigation bar has been created).
if (rootPopoverButtonItem != nil)
[detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
[detailViewController release];
#pragma mark -
#pragma mark Managing the popover
/*
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem
// Add the popover button to the left navigation item.
[navigationBar.topItem setLeftBarButtonItem:barButtonItem animated:NO];
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem
// Remove the popover button.
[navigationBar.topItem setLeftBarButtonItem:nil animated:NO];
*/
#pragma mark -
#pragma mark Memory management
- (void)dealloc
[popoverController release];
[rootPopoverButtonItem release];
[super dealloc];
@end
这是我收到警告的确切行的图像
【问题讨论】:
你已经把那个方法注释掉了......你期望发生什么? 【参考方案1】:您收到此警告的原因是因为UIViewController *detailViewController
UIViewController 没有名为“showRootPopoverButtonItem”的方法。如果您想摆脱警告,只需这样做:
[(WebViewController*)detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
或
[(Twitter*)detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
你只需要让它知道它不仅仅是一个 viewController,它是你创建的一个子类 viewController。所以无论什么类 showRootPopoverButtonItem: 你只需要类型转换它。
【讨论】:
【参考方案2】:如果您想保持代码完全相同但摆脱警告,您可以这样做。
if (rootPopoverButtonItem != nil)
[detailViewController performSelector:@selector(showRootPopoverButtonItem:) withObject:self.rootPopoverButtonItem];
如果你想更加小心,你应该使用这个。
if (rootPopoverButtonItem != nil && [detailViewController respondsToSelector:@selector(showRootPopoverButtonItem:)])
[detailViewController performSelector:@selector(showRootPopoverButtonItem:) withObject:self.rootPopoverButtonItem];
更新
阅读完您的代码后,您可以像在其他函数中一样在 detailViewController 上指定委托。
UIViewController<SubstitutableDetailViewController> *detailViewController = nil;
if (row == 0)
//...
【讨论】:
【参考方案3】:(1)指定详细ViewController的类型:[(TYPE *)OBJECTNAME...(2)然后指定方法调用[(TYPE *)OBJECTNAME METHODCALL];
(*) 您收到警告是因为编译器不知道您正在使用什么类型的对象。如果你继承了 UIViewController,那么你必须在访问方法时指定类型。确保方法在 .h 中,以便你可以访问它。
【讨论】:
以上是关于UIViewController 可能不响应 showRootPopoverButtonItem的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 UIViewController 不在其视图的响应者链中?
带有谷歌地图的 Iphone App + UIView 不响应滑动手势