Как включить задний/левый саблей в UINavigationController после установки leftBarButtonItem?

У меня проблема с здесь. По умолчанию в iOS7, жест назад салфетки в стеке UINavigationController может появиться представленный ViewController. Теперь я просто оформил весь стиль self.navigationItem.leftBarButtonItem для всех ViewControllers.

Вот код:

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:LOADIMAGE(@"back_button") style:UIBarButtonItemStylePlain target:self action:@selector(popCurrentViewController)];

после этого, navigationController.interactivePopGestureRecognizer отключен. Как я могу включить жест пота, не удаляя пользовательский leftBarButtonItem?

Спасибо!

Ответ 1

Сначала установите делегат в viewDidLoad:

self.navigationController.interactivePopGestureRecognizer.delegate = self;

И затем отключите жест при нажатии:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    [super pushViewController:viewController animated:animated];
    self.interactivePopGestureRecognizer.enabled = NO;
}

И включить в viewDidDisappear:

self.navigationController.interactivePopGestureRecognizer.enabled = YES;

Ответ 2

Он работает для меня, когда я устанавливаю делегат

self.navigationController.interactivePopGestureRecognizer.delegate = self;

а затем выполните

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

Ответ 3

он работает для меня Swift 3:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }

и в ViewDidLoad:

    self.navigationController?.interactivePopGestureRecognizer?.delegate = self
    self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true

Ответ 4

Вам нужно обработать два сценария:

  • Когда вы нажимаете новый вид на стек
  • Когда вы показываете контроллер корневого представления

Если вам просто нужен базовый класс, который вы можете использовать, здесь версия Swift 3:

import UIKit

final class SwipeNavigationController: UINavigationController {

    // MARK: - Lifecycle

    override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)
    }

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

        delegate = self
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // This needs to be in here, not in init
        interactivePopGestureRecognizer?.delegate = self
    }

    deinit {
        delegate = nil
        interactivePopGestureRecognizer?.delegate = nil
    }

    // MARK: - Overrides

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        duringPushAnimation = true

        super.pushViewController(viewController, animated: animated)
    }

    // MARK: - Private Properties

    fileprivate var duringPushAnimation = false

    // MARK: - Unsupported Initializers

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

}

// MARK: - UINavigationControllerDelegate

extension SwipeNavigationController: UINavigationControllerDelegate {

    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        guard let swipeNavigationController = navigationController as? SwipeNavigationController else { return }

        swipeNavigationController.duringPushAnimation = false
    }

}

// MARK: - UIGestureRecognizerDelegate

extension SwipeNavigationController: UIGestureRecognizerDelegate {

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        guard gestureRecognizer == interactivePopGestureRecognizer else {
            return true // default value
        }

        // Disable pop gesture in two situations:
        // 1) when the pop animation is in progress
        // 2) when user swipes quickly a couple of times and animations don't have time to be performed
        return viewControllers.count > 1 && duringPushAnimation == false
    }
}

Если вам нужно действовать как UINavigationControllerDelegate в другом классе, вы можете написать переадресатор делегатов похожий на этот ответ.

Адаптировано из источника в Objective-C: https://github.com/fastred/AHKNavigationController

Ответ 5

Это лучший способ включить/отключить прокрутку к контроллеру pop view в iOS 10, Swift 3:

Для первого экрана [где вы хотите отключить жестов прокрутки]:

class SignUpViewController : UIViewController,UIGestureRecognizerDelegate {

//MARK: - View initializers
override func viewDidLoad() {
    super.viewDidLoad()
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    swipeToPop()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func swipeToPop() {

    self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
    self.navigationController?.interactivePopGestureRecognizer?.delegate = self;
}

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {

    if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
        return false
    }
    return true
} }

Для среднего экрана [Если вы хотите включить жестов разворота]:

class FriendListViewController : UIViewController {

//MARK: - View initializers
override func viewDidLoad() {

    super.viewDidLoad()
    swipeToPop()
}

func swipeToPop() {

    self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
    self.navigationController?.interactivePopGestureRecognizer?.delegate = nil;
} }

Ответ 6

Настройка пользовательской кнопки "Назад" отключает функцию "Назад".

Самое лучшее, что нужно сделать, это подкласс UINavigationViewController и установить себя как делегат interactivePopGestureRecognizer; то вы можете вернуть YES из gestureRecognizerShouldBegin, чтобы позволить салфетки вернуться.

Например, это делается в AHKNavigationController

И версия Swift здесь: fooobar.com/questions/25993/...

Ответ 7

Swift 3:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return (otherGestureRecognizer is UIScreenEdgePanGestureRecognizer)
}

Ответ 8

Для тех, у кого по-прежнему возникают проблемы с этим, попробуйте разделить две строки, как показано ниже.

override func viewDidLoad() {
    self.navigationController!.interactivePopGestureRecognizer!.delegate = self
    ...

override func viewWillAppear(_ animated: Bool) {
    self.navigationController!.interactivePopGestureRecognizer!.isEnabled = true
    ...

Очевидно, что в моем приложении

interactivePopGestureRecognizer!.isEnabled

получил reset до false до того, как по какой-либо причине было показано представление.