我需要检测用户何时点击导航栏上的“后退”按钮,以便在发生这种情况时执行某些操作。我正试图手动设置一个动作到这样的按钮,这样:
[self.navigationItem.backBarButtonItem setAction:@selector(performBackNavigation:)];
- (void)performBackNavigation:(id)sender
{
// Do operations
[self.navigationController popViewControllerAnimated:NO];
}
我首先将该代码放在视图控制器本身中,但我发现self.navigationItem.backBarButtonItem
似乎是nil
,所以我将相同的代码移动到父视图控制器,后者将前者推送到导航堆栈。但我无法让它发挥作用。我已经阅读了一些关于这个问题的帖子,其中一些人说需要在父视图控制器上设置选择器,但对我来说它无论如何都不起作用......我可能做错了什么?
由于
答案 0 :(得分:127)
使用VIewWillDisappear
方法尝试使用此代码来检测按下NavigationItem的后退按钮:
-(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];
}
或者还有另一种获取导航BAck按钮动作的方法。
为后退按钮的UINavigationItem创建自定义按钮。
对于Ex:
在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];
}
斯威夫特:
override func willMoveToParentViewController(parent: UIViewController?)
{
if parent == nil
{
// Back btn Event handler
}
}
答案 1 :(得分:40)
override func didMoveToParentViewController(parent: UIViewController?) {
if parent == nil {
//"Back pressed"
}
}
答案 2 :(得分:16)
也许这个答案不符合您的解释,但问题标题。当您试图了解何时点击UINavigationBar
上的后退按钮时,此功能非常有用。
在这种情况下,您可以使用UINavigationBarDelegate
协议并实施以下方法之一:
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;
- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;
调用didPopItem
方法时,这是因为您点按了后退按钮或使用了[UINavigationBar popNavigationItemAnimated:]
方法,导航栏确实弹出了该项目。
现在,如果您想知道触发didPopItem
方法的操作,可以使用标记。
使用这种方法,我不需要手动添加带箭头图像的左侧栏按钮项目,以使其类似于iOS后退按钮,并且能够设置我的自定义目标/操作。
我有一个视图控制器,它有一个页面视图控制器和一个自定义页面指示器视图。我也使用自定义UINavigationBar来显示标题,以便知道我在哪个页面以及返回上一页的后退按钮。我也可以在页面控制器上滑动到上一页/下一页。
#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是动画的,我想立即处理后退按钮,而不是等到转换结束。
答案 3 :(得分:12)
didMoveToParentViewController
的问题是,一旦父视图再次完全可见就会调用它,所以如果你需要在此之前执行某些任务,它将无法工作。
它不适用于驱动动画手势。
使用willMoveToParentViewController
效果会更好。
<强>目标c 强>
- (void)willMoveToParentViewController:(UIViewController *)parent{
if (parent == NULL) {
// ...
}
}
<强>夫特强>
override func willMoveToParentViewController(parent: UIViewController?) {
if parent == nil {
// ...
}
}
答案 4 :(得分:6)
这是dadachi's的Objective-C版本答案:
- (void)didMoveToParentViewController:(UIViewController *)parent{
if (parent == NULL) {
NSLog(@"Back Pressed");
}
}
答案 5 :(得分:2)
设置UINavigationBar的委托,然后使用:
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
//handle the action here
}
答案 6 :(得分:1)
没有其他解决方案对我有用,但这确实可行:
创建自己的UINavigationController子类,使其实现UINavigationBarDelegate(无需手动设置导航栏的委托),添加UIViewController扩展,该扩展定义了在后退按钮按下时要调用的方法,然后在您的UINavigationController子类:
func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
self.topViewController?.methodToBeCalledOnBackButtonPress()
self.popViewController(animated: true)
return true
}
答案 7 :(得分:0)
使用自定义的UINavigationController
子类,该子类实现shouldPop
方法。
在Swift中:
class NavigationController: UINavigationController, UINavigationBarDelegate
{
var shouldPopHandler: (() -> Bool)?
func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool
{
if let shouldPopHandler = self.shouldPopHandler, !shouldPopHandler()
{
return false
}
self.popViewController(animated: true) // Needed!
return true
}
}
设置后,将调用您的shouldPopHandler()
来决定是否弹出控制器。如果未设置,它将照常弹出。
禁用UINavigationController
的{{1}}是个好主意,因为手势不会调用您的处理程序。
答案 8 :(得分:0)
在Swift 4或更高版本中:
$result2 = mysql_query("SELECT COUNT(*) FROM `Game_Items` WHERE `OWNER`='$player_send' && `Category`='Secondary' || `Category`='Armor'")
or die("Get count family stored items data connect to database failled!");
$row2 = mysql_fetch_array($result2);
$item_num = $row2[0];
if($item_num >= 1) return error;