ios - customize - swift navigation bar




Como ativar o gesto de deslizar para trás/esquerda no UINavigationController depois de definir o leftBarButtonItem? (6)

Eu tenho o problema oposto here . Por padrão no iOS7 , o gesto de deslizar para trás da UINavigationController do UINavigationController poderia estourar o ViewController apresentado. Agora eu apenas uniformizei todo o estilo self.navigationItem.leftBarButtonItem para todos os ViewControllers .

Aqui está o código:

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

depois disso, o navigationController.interactivePopGestureRecognizer está desabilitado. Como eu poderia ativar o gesto pop sem remover o personalizado leftBarButtonItem ?

Obrigado!


Definir um botão de retorno personalizado desativa o recurso de passagem para trás.

A melhor coisa a fazer para mantê-lo é subclassificar o UINavigationViewController e definir-se como o delegado interactivePopGestureRecognizer ; então você pode retornar YES de gestureRecognizerShouldBegin para permitir o retorno de volta.

Por exemplo, isso é feito no https://github.com/fastred/AHKNavigationController

E uma versão Swift aqui: https://.com/a/43433530/308315


Esta é a melhor maneira de ativar / desativar o controle de visualização pop no iOS 10, Swift 3 :

Para a primeira tela [onde você deseja desativar o gesto de deslize]:

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
} }

Para a tela intermediária [onde você deseja ativar o gesto de deslize]:

class FriendListViewController : UIViewController {

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

    super.viewDidLoad()
    swipeToPop()
}

func swipeToPop() {

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

Para aqueles que ainda estão tendo problemas com isso, tente separar as duas linhas conforme abaixo.

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

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

Obviamente, no meu aplicativo,

interactivePopGestureRecognizer! .isEnabled

foi redefinido para false antes que a exibição fosse exibida por algum motivo.


Primeiro set delegate in viewDidLoad:

self.navigationController.interactivePopGestureRecognizer.delegate = self;

E então desabilite o gesto ao pressionar:

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

E ative no viewDidDisappear:

self.navigationController.interactivePopGestureRecognizer.enabled = YES;

Além disso, adicione UINavigationControllerDelegate ao seu controlador de visualização.


Você precisa lidar com dois cenários:

  1. Quando você está empurrando uma nova visão para a pilha
  2. Quando você está mostrando o controlador de visualização raiz

Se você só precisa de uma classe base que possa usar, aqui está uma versão do 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
    }

    required init?(coder aDecoder: NSCoder) { 
        super.init(coder: aDecoder) 

        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: - 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
    }
}

Se você acabar precisando agir como um UINavigationControllerDelegate em outra classe, poderá escrever um encaminhador delegado semelhante a essa resposta .

Adaptado da fonte no Objective-C: https://github.com/fastred/AHKNavigationController


funciona para mim Swift 3 :

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

e no ViewDidLoad:

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






uinavigationitem