81 votes

Le bouton Précédent dans iOS 7 désactive le balayage pour revenir en arrière.

J'ai une application iOS 7 sur laquelle je configure un bouton de retour personnalisé comme ceci:

     UIImage *backButtonImage = [UIImage imageNamed:@"back-button"];
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];

    [backButton setImage:backButtonImage forState:UIControlStateNormal];
    backButton.frame = CGRectMake(0, 0, 20, 20);

    [backButton addTarget:self
                   action:@selector(popViewController)
         forControlEvents:UIControlEventTouchUpInside];

    UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    viewController.navigationItem.leftBarButtonItem = backBarButtonItem;
 

Mais cela désactive le geste "glisser de gauche à droite" iOS 7 pour naviguer vers le contrôleur précédent. Est-ce que quelqu'un sait comment je peux définir un bouton personnalisé tout en maintenant ce geste activé?

EDIT: J'ai essayé de définir plutôt viewController.navigationItem.backBarButtonItem, mais cela ne semble pas afficher mon image personnalisée.

83voto

Paul Hunter Points 2708

IMPORTANT: Ceci est un hack. Je recommanderais de jeter un coup d'œil à la réponse de Dan_Gabicoware.

Appeler la ligne suivante après avoir affecté les leftBarButtonItem travaillés pour moi:

 self.navigationController.interactivePopGestureRecognizer.delegate = self;
 

Edit: Cela ne fonctionne pas s’il est appelé dans les méthodes init . Il devrait être appelé dans viewDidLoad ou des méthodes similaires.

56voto

Dan_Gabicoware Points 829

Utiliser le backIndicatorImage et backIndicatorTransitionMaskImage propriétés de la UINavigationBar si possible. La définition de ces sur un UIAppearanceProxy pouvez facilement modifier le comportement de votre application. La ride est que vous ne pouvez définir que ceux sur ios 7, mais cela fonctionne parce que vous ne pouvez utiliser le menu geste sur ios 7 de toute façon. Normal de votre ios 6 style peut rester intact.

UINavigationBar* appearanceNavigationBar = [UINavigationBar appearance];
//the appearanceProxy returns NO, so ask the class directly
if ([[UINavigationBar class] instancesRespondToSelector:@selector(setBackIndicatorImage:)])
{
    appearanceNavigationBar.backIndicatorImage = [UIImage imageNamed:@"back"];
    appearanceNavigationBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:@"back"];
    //sets back button color
    appearanceNavigationBar.tintColor = [UIColor whiteColor];
}else{
    //do ios 6 customization
}

Essayer de manipuler les interactivePopGestureRecognizer délégué du conduire à beaucoup de problèmes.

29voto

Nick H247 Points 2840

J'ai vu cette solution http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/ qui sous-classes UINavigationController. Son d'une meilleure solution, car il traite le cas où vous faites glisser avant que le contrôleur est en place - ce qui provoque une collision.

En outre, j'ai remarqué que si vous faites un glissement sur la racine de la vue-contrôleur (après avoir cliqué sur l'un, et le dos encore une fois, l'INTERFACE utilisateur ne répond plus. (aussi le même problème dans la réponse ci-dessus).

Donc le code dans la sous-classé UINavigationController devrait ressemble à:

@implementation NavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    __weak NavigationController *weakSelf = self;

    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.delegate = weakSelf;
        self.delegate = weakSelf;
    }
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    // Hijack the push method to disable the gesture
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
        self.interactivePopGestureRecognizer.enabled = NO;

    [super pushViewController:viewController animated:animated];
}

#pragma mark - UINavigationControllerDelegate

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animate {
    // Enable the gesture again once the new controller is shown
    self.interactivePopGestureRecognizer.enabled = ([self respondsToSelector:@selector(interactivePopGestureRecognizer)] && [self.viewControllers count] > 1);
}

@end

19voto

Albert Chu Points 113

j'utilise

 [[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"nav_back.png"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"nav_back.png"]];

[UIBarButtonItem.appearance setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -64) forBarMetrics:UIBarMetricsDefault];
 

6voto

iwill Points 845
navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;

C'est à partir de http://stuartkhall.com/posts/ios-7-development-tips-tricks-hacksmais il provoque plusieurs bugs:

  1. Pousser un autre viewController dans le navigationController quand un balayage à partir du bord gauche de l'écran;
  2. Ou, balayez à partir du bord gauche de l'écran lorsque le topViewController est surgissent de la navigationController;

par exemple, Lorsque le rootViewController de navigationController montre, balayez à partir du bord gauche de l'écran, et appuyez sur quelque chose(RAPIDEMENT) pour pousser anotherViewController dans le navigationController, puis

  • Le rootViewController ne répond pas tout événement tactile;
  • Le anotherViewController ne sera pas affichée;
  • Balayez à partir du bord de l'écran à nouveau, le anotherViewController va être montré;
  • Appuyez sur la coutume de bouton de retour à la pop la anotherViewController, crash!

Si vous devez mettre en œuvre UIGestureRecognizerDelegate méthode en soi.navigationController.interactivePopGestureRecognizer.délégué comme ceci:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer == navigationController.interactivePopGestureRecognizer) {
        return !navigationController.<#TODO: isPushAnimating#> && [navigationController.viewControllers count] > 1;
    }
    return YES;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X