由于一个奇怪的请求,我试图拒绝,但它没有工作,我不得不覆盖导航栏的背后按钮。
我做了一个定制的UINavigationController子类,并黑掉了- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item方法。
这是我的代码:
@interface CustomUINavigationController ()
@end
@implementation CustomUINavigationController
#pragma mark - UINavigationBar delegate methods
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
if ([[self.viewControllers lastObject] isKindOfClass:[ViewController1 class]]) {
ViewController1 *vc1 = (ViewController1 *)[self.viewControllers lastObject];
[vc1 handleBackAction];
if (vc1.canPopVC == YES) {
[self popViewControllerAnimated:YES];
return YES;
} else {
return NO;
}
}
[self popViewControllerAnimated:YES];
return YES;
}
@end除了我以编程方式弹出一个viewController之外,所有这些都很好。每当我想在说到pop之后执行推送时,这个应用程序就会崩溃。转NSZombie on,显示当以编程方式弹出一个viewController时,它的父viewController将被取消分配。此时,定制backButton并不是一个选项,因为它将失去本机iOS 7的popViewController功能。
撞车日志:
*** -[ContactsDetailViewController performSelector:withObject:withObject:]: message sent to deallocated instance 0x1806b790发布于 2013-12-02 11:37:33
我不是百分之百确定,但我认为您不应该真的在那个委托方法中弹出视图控制器。
“应该”委托方法通常不会做一些事情。他们只是断言某件事应该做还是不该做。
把你的方法改成这个..。
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
if ([[self.viewControllers lastObject] isKindOfClass:[ViewController1 class]]) {
ViewController1 *vc1 = (ViewController1 *)[self.viewControllers lastObject];
[vc1 handleBackAction];
if (vc1.canPopVC == YES) {
return YES;
} else {
return NO;
}
}
return YES;
}看看能不能用。
我所做的就是删除popViewController调用。
编辑-如何添加自定义回退按钮
在UIBarButtonItem的一个分类里..。
+ (UIBarButtonItem *)customBackButtonWithTarget:(id)target action:(@SEL)action
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage:[UIImage imageNamed:@"Some image"] forState:UIControlStateNormal];
[button setTitle:@"Some Title" forState:UIControlStateNormal];
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button];
return barButtonItem;
}现在只要你想设置一个自定义的后退按钮就用..。
UIBarButtonItem *backButton = [UIBarButtonItem customBackButtonWithTarget:self action:@selector(backButtonPressed)];发布于 2014-09-28 10:53:09
(我上一篇文章完全错了。这是一个完整的重写,有一个适当的解决方案。)
当我选择删除一些代码时会弹出这种行为,当我转换到ARC时会产生警告--我认为这些代码没有被调用。
这里是情况:
如果将navigationBar:shouldPopItem:隐藏在UINavigationController的子类中,那么当用户触摸NavBar的BACK按钮时,将不会弹出当前的视图控制器。但是,如果直接调用popViewControllerAnimated:,则仍将调用navigationBar:shouldPopItem:,视图控制器将弹出。
这里是为什么当用户触摸后退按钮时视图控制器无法弹出的原因:
UINavigationController有一个名为navigationBar:shouldPopItem:的隐藏方法。当用户单击“后退”按钮时,将调用此方法,当用户单击“后退”按钮时,该方法通常会调用popViewControllerAnimated:。
当您隐藏navigationBar:shouldPopItem:时,不会调用超类的实现,因此不会弹出ViewController。
为什么不应该在子类“popViewControllerAnimated: navigationBar:shouldPopItem:**:**”中调用
如果在popViewControllerAnimated:中调用navigationBar:shouldPopItem:,当您单击NavBar上的BACK按钮时,您将看到您想要的行为:您可以确定是否要弹出,如果愿意,视图控制器会弹出。
但是,如果直接调用popViewControllerAnimated:,最终将弹出两个视图控制器:一个来自对popViewControllerAnimated:的直接调用,另一个来自添加到navigationBar:shouldPopItem:中的调用。
我认为是安全的解决方案:
您的自定义导航控制器应该如下所示:
@interface CustomNavigationController : UINavigationController <UINavigationBarDelegate>
{
// .. any ivars you want
}
@end您的实现应该包含如下代码:
// Required to prevent a warning for the call [super navigationBar:navigationBar shouldPopItem:item]
@interface UINavigationController () <UINavigationBarDelegate>
@end
@implementation CustomNavigationController
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
BOOL rv = TRUE;
if ( /* some condition to determine should NOT pop */ )
{
// we won't pop
rv = FALSE;
// extra code you might want to execute ...
} else
{
// It's not documented that the super implements this method, so we're being safe
if ([[CustomNavigationController superclass]
instancesRespondToSelector:@selector(navigationBar:shouldPopItem:)])
{
// Allow the super class to do its thing, which includes popping the view controller
rv = [super navigationBar:navigationBar shouldPopItem:item];
}
}
return rv;
}发布于 2013-12-02 11:50:46
我建议采取完全不同的方法。
为要在导航堆栈上推送的视图控制器创建一个基类。在viewDidLoad方法中,将自定义按钮设置为navigationItem的leftBarButtonItem,并添加一个-backAction:,该-backAction:调用导航控制器的popViewControllerAnimated:方法。
这样,您就不会关心一些事情,比如失去UINavigationController的功能,比如向pop滑动,并且根本不必覆盖navigationBar:shouldPopItem:方法。
https://stackoverflow.com/questions/20327165
复制相似问题