尝试在iOS中处理“返回”导航button操作
我需要检测用户点击导航栏上的“后退”button,以便在发生这种情况时执行某些操作。 我试图手动设置这样的button,这样的行动:
[self.navigationItem.backBarButtonItem setAction:@selector(performBackNavigation:)]; - (void)performBackNavigation:(id)sender { // Do operations [self.navigationController popViewControllerAnimated:NO]; }
我首先将代码放在视图控制器本身,但是我发现self.navigationItem.backBarButtonItem
似乎是nil
,所以我将相同的代码移动到父视图控制器,它将前者推到导航堆栈。 但我无法做到这一点。 我已经阅读了关于这个问题的一些post,其中一些人说,select器需要设置在父视图控制器,但对我来说它不工作呢…我做错了什么?
谢谢
使用VIewWillDisappear
方法试试这个代码来检测按下NavigationItem的后退button:
-(void) viewWillDisappear:(BOOL)animated { if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) { // Navigation button was pressed. Do some stuff [self.navigationController popViewControllerAnimated:NO]; } [super viewWillDisappear:animated]; }
或者有另一种方法来获得导航BAckbutton的动作。
为后退button的UINavigationItem创build自定义button。
例如:
在ViewDidLoad中:
- (void)viewDidLoad { [super viewDidLoad]; UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Home" style:UIBarButtonItemStyleBordered target:self action:@selector(home:)]; self.navigationItem.leftBarButtonItem=newBackButton; } -(void)home:(UIBarButtonItem *)sender { [self.navigationController popToRootViewControllerAnimated:YES]; }
Swift:
override func willMoveToParentViewController(parent: UIViewController?) { if parent == nil { // Back btn Event handler } }
迅速
override func didMoveToParentViewController(parent: UIViewController?) { if parent == nil { //"Back pressed" } }
也许这个答案不适合你的解释,但问题的标题。 当你试图知道你什么时候点击了UINavigationBar
上的后退button时这很有用。
在这种情况下,您可以使用UINavigationBarDelegate
协议并实现以下方法之一:
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item; - (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;
当didPopItem
方法被调用时,这是因为你点击了后退button,或者你使用了[UINavigationBar popNavigationItemAnimated:]
方法,并且导航栏确实popup了该项目。
现在,如果你想知道什么动作触发了didPopItem
方法,你可以使用一个标志。
使用这种方法,我不需要手动添加带有箭头图像的左侧栏button项目,以使其与iOS后退button类似,并且能够设置我的自定义目标/操作。
我们来看一个例子:
我有一个视图控制器,有一个页面视图控制器和自定义页面指示器视图。 我也使用一个自定义的UINavigationBar来显示一个标题,知道我是在哪个页面上,后退button可以回到上一页。 而且我也可以滑动到页面控制器的上一页/下一页。
#pragma mark - UIPageViewController Delegate Methods - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed { if( completed ) { //... if( currentIndex > lastIndex ) { UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"Some page title"]; [[_someViewController navigationBar] pushNavigationItem:navigationItem animated:YES]; [[_someViewController pageControl] setCurrentPage:currentIndex]; } else { _autoPop = YES; //We pop the item automatically from code. [[_someViewController navigationBar] popNavigationItemAnimated:YES]; [[_someViewController pageControl] setCurrentPage:currentIndex]; } } }
那么我实现UINavigationBar委托方法:
#pragma mark - UINavigationBar Delegate Methods - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { if( !_autoPop ) { //Pop by back button tap } else { //Pop from code } _autoPop = NO; return YES; }
在这种情况下,我使用了shouldPopItem
因为pop是animation的,我想立即处理后退button,不要等到转换完成。
与didMoveToParentViewController
的问题是,它被调用,一旦父视图再次完全可见,所以如果你需要执行一些任务之前,它将无法正常工作。
而且它不适用于驱动的animation手势。 使用willMoveToParentViewController
效果更好。
Objective-C的
- (void)willMoveToParentViewController:(UIViewController *)parent{ if (parent == NULL) { // ... } }
迅速
override func willMoveToParentViewController(parent: UIViewController?) { if parent == nil { // ... } }
这是dadachi的 Objective-C版本答案:
Objective-C的
- (void)didMoveToParentViewController:(UIViewController *)parent{ if (parent == NULL) { NSLog(@"Back Pressed"); } }
设置UINavigationBar的委托,然后使用:
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { //handle the action here }
设置UINavigationControllerDelegate并实现这个委托func(Swift):
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) { if viewController is <target class> { //if the only way to get back - back button was pressed } }