Définir une Image personnalisée pour un bouton de retour sur UINavigationBar

j'essaie de définir une image personnalisée pour le bouton arrière qui se place automatiquement sur une barre de navigation quand une nouvelle vue est poussée sur la pile.

j'ai essayé d'ajouter ce qui suit dans le viewDidLoad du viewController parent:

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:[UIImage imageNamed:@"BackButton.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

j'ai aussi essayé ce qui suit:

UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"BackButton.png"] style:UIBarButtonItemStyleBordered target:nil action:nil];
    self.navigationItem.backBarButtonItem = btn;

en utilisant UIAppearance produit des résultats assez étranges: The BackButton image seems to be placed underneath the original title

12
demandé sur Paul Morris 2012-06-13 21:10:17

7 réponses

essayez ce code

UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
UIImage *backBtnImage = [UIImage imageNamed:@"BackBtn.png"]  ;  
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];  
[backBtn addTarget:self action:@selector(goback) forControlEvents:UIControlEventTouchUpInside];  
backBtn.frame = CGRectMake(0, 0, 54, 30);  
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:backBtn] ;  
self.navigationItem.leftBarButtonItem = backButton;

puis définir la méthode de goback comme ceci

- (void)goback
{
    [self.navigationController popViewControllerAnimated:YES];
}
35
répondu Piyush Kashyap 2012-06-13 18:27:47

depuis iOS 7.0 il y a une nouvelle méthode dans L'API backIndicatorImage . Vous pouvez l'utiliser à la place de setBackButtonBackgroundImage si vous ne voulez pas que l'image soit étirée pour correspondre au texte (par exemple si vous voulez une taille fixe personnalisé flèche arrière). Voici un exemple dans swift:

let image = UIImage(named: "back_button")

UINavigationBar.appearance().backIndicatorImage = image
UINavigationBar.appearance().backIndicatorTransitionMaskImage = image

vous pouvez cacher le texte à partir du bouton en utilisant cette astuce:

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -66), for: .default)
26
répondu Konstantin Kalbazov 2017-03-07 10:52:12

C'est le code que j'utilise et fonctionne parfaitement dans ma propre application iOS 5. Ce code est de application:didFinishLaunchingWithOptions: dans le délégué app:

UIImage * backButtonImage = [UIImage imageNamed: @"back-button-image"];
backButtonImage = [backButtonImage stretchableImageWithLeftCapWidth: 15.0 topCapHeight: 30.0];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage: backButtonImage forState: UIControlStateNormal barMetrics: UIBarMetricsDefault];

vous aurez peut-être besoin d'utiliser une image extensible, où le "point" à gauche est le cap gauche


ou en Swift

let backButtonImage = UIImage(named: "back-button-image")
backButtonImage = backButtonImage?.stretchableImageWithLeftCapWidth(15, topCapHeight: 30)
UIBarButtonItem.appearance().setBackButtonBackgroundImage(backButtonImage, forState: .Normal, barMetrics: .Default)
19
répondu Ashley Mills 2015-04-24 08:07:37

version iOS 8+ Swift (peut être converti en ObjC avec peu d'effort). Cette méthode préserve tous les avantages et le comportement de la barre de navigation liée au bouton arrière standard (animation sur poussoir/popping, geste pop interactif, etc)

// Call the code ONE TIME somewhere on app launch to setup custom back button appearance
UINavigationBar.appearance().tintColor = UIColor.blackColor()
// If you need custom positioning for your back button, in this example button will be 1 px up compared to default one
// Also only vertical positioning works, for horizontal add offsets directly to the image
let backImageInsets = UIEdgeInsetsMake(0, 0, -1, 0)
// Get image, change of rendering (so it preserves offsets made in file), applying offsets
let backImage = UIImage(named: "YourButtonImageAssetFileName")?.imageWithRenderingMode(.AlwaysOriginal).imageWithAlignmentRectInsets(backImageInsets)
// Setting images
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage

// Call EACH TIME BEFORE pushing view controller if you don't need title near your back button arrow
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
// Push controller
self.navigationController?.pushViewController(vc, animated: true)
4
répondu Andrei Konstantinov 2016-08-12 13:09:44

essayez le code ci-dessous, ça marche pour moi:

[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"back-button-image"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"back-button-image"]];
2
répondu pragmus 2016-03-31 08:38:35

cela a fonctionné pour moi:

let button1 = UIBarButtonItem(
    image: #imageLiteral(resourceName: "back_arrow"), 
    style: .plain, 
    target: self, 
    action: #selector(self.backBtnTapped(_:))
)
self.navigationItem.leftBarButtonItem  = button1
0
répondu user3780949 2017-05-04 13:27:04

ce code travaillé pour Swift 4 et XCode 9.4 :

ajouter ce code au func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool D'AppDelegate pour S'appliquer à tous les contrôleurs de votre vue:

//Custom back button
    let barButtonItemAppearance = UIBarButtonItem.appearance()
    barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
    barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .highlighted)
    let backImg: UIImage = UIImage(named: "back")!
    barButtonItemAppearance.setBackButtonBackgroundImage(backImg, for: .normal, barMetrics: .default)

    let image = UIImage()

    UINavigationBar.appearance().backIndicatorImage = image
    UINavigationBar.appearance().backIndicatorTransitionMaskImage = image
0
répondu mkhoshpour 2018-07-03 04:34:37