J'utilise un bouton de retour personnalisé dans mon application. Ce bouton de retour personnalisé est défini globalement comme ceci:
UINavigationBar.appearance().backIndicatorImage = UIImage(named: "Back").withRenderingMode(.alwaysOriginal)
UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(asset: .back).withRenderingMode(.alwaysOriginal)
Avant iOS 11, ce code faisait l'affaire, mais maintenant dans iOS 11, le bouton n'est plus centré verticalement, comme vous pouvez le voir ici:
Je pouvais modifier la hauteur de l'image du bouton de retour à 44, mais cela se briserait sous iOS <11. Je pourrais également utiliser deux images différentes, mais je recherchais quelque chose de plus net, comme un moyen de centrer verticalement l'image à l'arrière bouton contenant la vue.
MODIFIER:
Il s'avère que, comme l'a dit banxii1988, le problème est dû à setBackButtonTitlePositionAdjustment
lorsque les valeurs déplacent délibérément le titre en dehors de l'écran visible. C'était un hack pour éviter de supprimer le titre du bouton de retour dans chaque contrôleur de vue. J'ai décidé de supprimer ce hack et j'ai fait ce qu'il fallait:
" "
.backBarButtonItem
par programmation navigationItem.backBarButtonItem = UIBarButtonItem(title: "",
style: .plain, target: nil, action: nil)
Notez que le titre du bouton Précédent que vous voyez dans un contrôleur de vue est défini dans le précédent dans la pile de navigation.
1) enlevez PositionAdjustment s'il y en a. tel que
bap.setBackButtonTitlePositionAdjustment(UIOffset(horizontal: 0, vertical: -64), for: .default)
2) vérifier si le précédent ViewController dans la pile de navigation a un titre
Je pense que cette méthode est ok! C'est utile pour moi.
if(@available(iOS 11, *)) {
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal];
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateHighlighted];
} else {
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-60, -60) forBarMetrics:UIBarMetricsDefault];
}
Pour ceux qui ne pourraient pas le résoudre:
1) Dans votre projet (cmd + shift + f), recherchez "setBackButtonTitle", vous trouverez un code comme ci-dessous:
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[xController class]]] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];
2) Changer le code ci-dessus avec celui-ci:
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[xController class]]] setBackButtonTitlePositionAdjustment:UIOffsetMake(-200, 0) forBarMetrics:UIBarMetricsDefault];
Depuis iOS 11, le code ci-dessus sert à masquer les titres des boutons, le bouton précédent et le titre lui-même. Cependant, si vous déplacez simplement le titre du bouton de retour horizontalement, tout fonctionne correctement et il n'y a pas de tirage en arrière.
Cette solution fonctionne pour moi pour iOS 9, 10 et 11
var backButtonImage: UIImage = UIImage(named: "backButton")!
UINavigationBar.appearance().backIndicatorImage = backButtonImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backButtonImage
if #available(iOS 11, *) {
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(-300, 0), for:UIBarMetrics.default)
} else {
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -200), for:UIBarMetrics.default)
}
Après plusieurs tentatives et échecs, cela a fonctionné pour nous pour iOS 11:
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-200, -5) forBarMetrics:UIBarMetricsDefault];
L'astuce consistait à déplacer le texte "Retour" sur l'axe des abscisses, et un peu sur l'axe des ordonnées, car setBackButtonTitlePositionAdjustment
s'est avéré affecter à la fois l'image et le texte.
Cependant, nous ne savons pas combien de temps cette solution fonctionnera, elle pourrait être "réparée" par Apple à tout moment
je recommanderais la méthode swizzling pour le résoudre, j'ai utilisé cette solution dans certains de mes projets et cela fonctionne bien.
1 - créer une catégorie de UIViewController
.
2- importer #import <objc/runtime.h>
.
3- coller la méthode suivante
#import "UIViewController+Extras.h"
#import <objc/runtime.h>
@implementation UIViewController (Extras)
+ (void)load {
static dispatch_once_t once_token;
dispatch_once(&once_token, ^{
SEL viewDidLoadSelector = @selector(viewDidLoad);
SEL viewDidLoadModifyBackButtonSelector = @selector(modifyBackButton_viewDidLoad);
Method originalMethod = class_getInstanceMethod(self, viewDidLoadSelector);
Method extendedMethod = class_getInstanceMethod(self, viewDidLoadModifyBackButtonSelector);
method_exchangeImplementations(originalMethod, extendedMethod);
});
}
- (void)modifyBackButton_viewDidLoad {
[self modifyBackButton_viewDidLoad];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:self.navigationItem.backBarButtonItem.style target:nil action:nil];
}
@end
if(@available(iOS 11, *)) {
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal];
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateHighlighted];
} else {
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-60, -60) forBarMetrics:UIBarMetricsDefault];
}
La solution ci-dessus de @Tonin fonctionne, mais le seul souci est que le texte du bouton gauche de la barre de navigation (comme "Annuler") est transparent (couleur claire) lorsqu'il est partagé avec une autre application (email, message, etc.)
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[title, URL] applicationActivities:nil];
[activityViewController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
// set clear color when back from share
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal];
}];
[self presentViewController:activityViewController animated:YES completion:^{
// set white color when share to other app
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]} forState:UIControlStateNormal];
}];
1.
extension UINavigationController {
func pushViewC(_ viewController: UIViewController, animated: Bool) {
viewController.navigationItem.leftBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "return").withRenderingMode(.alwaysOriginal), style: .plain, target: navigationController, action: #selector(popViewController(animated:)))
pushViewController(viewController, animated: animated)
}
}
2. utiliser pushViewC au lieu de pushViewController
navigationController?.pushViewC(otherVC, animated: true)
if #available(iOS 11, *) {
UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal)
UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .highlighted)
} else {
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0,
-60), for:UIBarMetrics.default)
}