【问题标题】:Find out if user pressed the back button in uinavigationcontroller?找出用户是否按下了 uinavigationcontroller 中的后退按钮?
【发布时间】:2023-04-04 05:13:01
【问题描述】:

当视图加载时,我想看看是不是因为用户按下了后退按钮。我该如何检查?

【问题讨论】:

  • 您想知道是用户发起弹出还是一般弹出?
  • 最好详细说明您的总体目标。可能有一种更简单的方法来做你想做的事情。例如,如果您需要知道在第二个视图中是否更改或设置了某个值,您只需检查该值即可。
  • 弹出是我想被告知的。

标签: iphone objective-c


【解决方案1】:

我发现检测 UINavigationController 的后退按钮按下(iOS 5.0 之前)的最佳解决方案是验证当前视图控制器不存在于导航控制器的视图控制器堆栈中。

- (void)viewDidDisappear:(BOOL)animated 中检查这个条件可能更安全,因为逻辑上,在调用该方法时,视图控制器极有可能从堆栈中删除。

iOS 5.0 之前的版本:

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    if (![[self.navigationController viewControllers] containsObject:self]) {
        // We were removed from the navigation controller's view controller stack
        // thus, we can infer that the back button was pressed
    }
}

iOS 5.0+ 你可以使用-didMoveToParentViewController:

- (void)didMoveToParentViewController:(UIViewController *)parent
{
    // parent is nil if this view controller was removed
}

【讨论】:

  • 这很好用!但是你提到了pre-iOS 5.0.. 有没有iOS 5 特定的方法可以用来捕捉返回按钮回调?
  • 在推送 VC 时也会调用它(至少在 iOS 6 上)。
  • 嘿,我在 iOS 4.3 中没有调用 viewDidDisappear。虽然在 iOS 5 中我调用了这两种方法。有什么想法吗?
  • didMoveToParentViewController;不是很好的解决方案,出现这个视图时也会调用。
  • 你需要检查parent是否为nil,以确定视图是被添加还是被移除。
【解决方案2】:

在你看来WillDisappear 方法检查

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    if ([self isMovingFromParentViewController]) {
      //specific stuff for being popped off stack
    }
}

这仅适用于 iOS 5 后

【讨论】:

  • if 语句中缺少括号,但在其他方面非常有用的答案。谢谢!
  • 作为替代方案,受 Andrew 的回答启发,您可以在移动之前通过覆盖 willMoveToParentViewController: 而不是 didMoveToParentViewController: 来做一些事情。
  • 比编写自定义按钮更好的方法。谢谢。
  • 这并不意味着用户是否按下返回按钮。触发时还有很多其他情况
【解决方案3】:

UINavigationController 有一个delegate 属性,用于发出委托回调。请参阅the iOS reference here

委托没有“按下后退按钮”回调,而是告诉您导航堆栈上何时出现某些内容。当您按下返回时,您正在从堆栈中“弹出”顶部视图控制器,因此它会告诉您该视图即将出现。我认为这是您要寻找的回调。

您可以有一些简单的逻辑来检查是否是“感兴趣”的视图控制器,然后您可以发送通知等。

【讨论】:

  • 没有任何委托显示 uinavigationcontroller 何时从堆栈中弹出
  • 我说 UINavigationController 有一个委托。如果 UINavigationController 正在管理您的视图层次结构,它确实会回调到委托(如果已设置)。
  • 我正在尝试这样做。不幸的是,在备份时,它在为同一个视图控制器调用委托方法 -navigationController:willShowViewContoller:animated: 之前调用“新”视图控制器 [正在备份的那个] -viewWillAppear...
【解决方案4】:

为了完整起见,在 Swift 中混合使用两个最受好评的答案(12):

override func willMoveToParentViewController(parent: UIViewController?) {
    super.willMoveToParentViewController(parent)
    if parent == nil {
        // view controller is popping
    }
}

【讨论】:

  • 不要使用will,使用did,因为有屏幕边缘弹出手势。
【解决方案5】:

这是一个稍微不同的场景,但我认为该解决方案可能会帮助其他人。

在我的情况下,我在 UIPopoverController 中有一个 UINavigationController。我需要检测用户是否单击了后退按钮,或者单击了弹出框之外。为此,我检查了 viewWillDisappear 中的 visibleViewController 属性。如果关闭时视图控制器仍然是 visibleViewController,则弹出框正在通过另一种方式关闭。如果关闭时视图控制器不是 visibleViewController,则按下返回按钮。

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    if (self.navigationController.visibleViewController != self) {
        <Do something since we're closing using something else>
    } else {
        <Do something since we're closing because of the back button>
    }
}

我尝试使用 zach 的解决方案,但 isMovingFromParentViewController 在两种情况下都返回 true。

我验证了这在 iOS 5+ 中有效

我希望这会有所帮助。

【讨论】:

    【解决方案6】:

    创建自定义后退栏按钮并设置目标,

    第 1 步:将这些方法添加到您的类中

    - (void)backButtonClicked :(id)sender{
        [self.navigationController popViewControllerAnimated:YES];
    }
    
    - (void)addBackBarButton{
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(0, 0, 55, 35);
        [button setTitle:@"back" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(backButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
        UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
        self.navigationItem.leftBarButtonItem = customBarItem;
    }
    

    第二步:在viewDiDLoad方法中调用[self addBackBarButton];

    您将在 backButtonClicked 方法中获得操作。你可以随心所欲地使用它。

    干杯!

    【讨论】:

      【解决方案7】:

      要确定它是返回按钮,唯一的方法是创建一个自定义按钮。如果您不知道该怎么做,请查看tutorial。它看起来不像普通的后退按钮,而是关闭。如果您需要更多帮助,请发表评论

      【讨论】:

      • 检查 andrews 其他答案,如果发帖人读到这个可能会接受它作为正确答案
      • @user461864,你的意思是另一个安德鲁,而不是安德鲁的另一个答案——他们是不同的安德鲁。但是您是对的,另一个答案要好得多;相比之下,现在的工作要做很多额外的工作。
      • 该死,你是对的,.. 我觉得他回答了两次很奇怪,但这解释了
      • 这个答案不正确,应该被发帖者删除。
      • 天哪,他们都叫安德鲁!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多