在UINavigationbar后退按钮和交互式弹出式滑动之间进行辨别以便返回?

时间:2015-02-02 14:12:16

标签: ios cocoa-touch uinavigationcontroller

我需要辨别两种返回iOS的方法 - 点击导航栏中的后退按钮,然后使用屏幕边缘平移来执行此操作。如果可能的话,我宁愿不实现自定义后退按钮。

我怎么能这个呢?

3 个答案:

答案 0 :(得分:0)

想出来:

我已经实现了UINavigationControllerDelegate,将自己声明为该委托,并设置了一个名为isPanningBack的布尔值。然后实现了这个人;

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    id<UIViewControllerTransitionCoordinator> tc = navigationController.topViewController.transitionCoordinator;
    [tc notifyWhenInteractionEndsUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        if (![context isCancelled]) {
            _isPanningBack = YES;
        }
    }];
}

然后,实施viewDidDisappear:animated

- (void)viewDidDisappear:(BOOL)animated
{
    if (!_isPanningBack) {
        // We can be sure that we used the chevron.
    } else {
        // We can be sure that we used the swipe.
    }
    [super viewDidDisappear:animated];
}

答案 1 :(得分:0)

如果你像我一样尝试了上面的解决方案,但需要在调用 viewWillAppear之前知道,我想出了以下解决方案,以区分由后退按钮和由交互式滑动触发的按钮。

class SpendingCardContainedNavigationController: UINavigationController, UIGestureRecognizerDelegate, UINavigationControllerDelegate {

    private var poppingFromSwipe = false

    override init(navigationBarClass: AnyClass?, toolbarClass: AnyClass?) {
        super.init(navigationBarClass: navigationBarClass, toolbarClass: toolbarClass)
        delegate = self
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        delegate = self
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        // Prevents a known, albeit a rare, bug 
        guard viewControllers.count > 1 else { return false }
        poppingFromSwipe = true
        return true
    }

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        interactivePopGestureRecognizer?.delegate = self
        if !poppingFromSwipe {
            viewController.doSomethingUseful()
        }
        poppingFromSwipe = false
    }

    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        interactivePopGestureRecognizer?.delegate = self
        viewController.doSomethingElseUseful()
    }
}

此方法允许您对viewControllerwillShow中的didShow执行操作。您甚至可以继续UIViewController的子类并添加isBeingDismissedInteractively var,然后在viewWillAppear以及isBeingDismissedisMovingFromParentViewController中进行检查但这对我来说太过分了。

希望这有助于某人!

答案 2 :(得分:0)

对于仍在寻找其他解决方案的任何人,我曾经检查过状态,但没有在上面引用我

if self.navigationController?.interactivePopGestureRecognizer?.state == .began {
  // Gesture bagan 
}