web-dev-qa-db-fra.com

Bouton de retour rapide de la barre de navigation personnalisée Swift, image et texte

Je dois personnaliser l'aspect d'un bouton de retour dans un projet Swift.

Voici ce que j'ai:  Default Back Button

Voici ce que je veux:  Custom Back Button

J'ai essayé de créer mon propre UIBarButtonItem mais je ne peux pas comprendre comment obtenir l'image à côté du texte plutôt que comme arrière-plan ou remplacement du texte.

let backButton = UIBarButtonItem(title: "Custom", style: .Plain, target: self, action: nil    )
//backButton.image = UIImage(named: "imageName") //Replaces title
backButton.setBackgroundImage(UIImage(named: "imageName"), forState: .Normal, barMetrics: .Default) // Stretches image
navigationItem.setLeftBarButtonItem(backButton, animated: false)
28
Conor

Vous pouvez faire quelque chose comme ça:

let yourBackImage = UIImage(named: "back_button_image")
self.navigationController?.navigationBar.backIndicatorImage = yourBackImage
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
self.navigationController?.navigationBar.backItem?.title = "Custom"

Votre image n'aura qu'une couleur si

50
Randy

Remarque : N'oubliez pas que le bouton Précédent appartient au ViewController source et non au ViewController de destination. Ainsi, la modification doit être effectuée dans le VC source, ce qui est répercuté sur toute la vue du contrôleur de navigation.

Extrait de code: 

let backImage = UIImage(named: "icon-back")

self.navigationController?.navigationBar.backIndicatorImage = backImage

self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage

/*** If needed Assign Title Here ***/
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: nil, action: nil)
26
Supratik Majumdar

Swift 4

Dans mon cas, je n'avais besoin que de l'image du bouton, sans aucun texte. J'espère que cela sera utile à quelqu'un. 

let imgBackArrow = UIImage(named: "back_arrow_32")

navigationController?.navigationBar.backIndicatorImage = imgBackArrow
navigationController?.navigationBar.backIndicatorTransitionMaskImage = imgBackArrow

navigationItem.leftItemsSupplementBackButton = true
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)

Pour iOS 12, vous pouvez faire

func setNavigationBar() {

    self.navigationItem.setHidesBackButton(true, animated:false)

    //your custom view for back image with custom size
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
    let imageView = UIImageView(frame: CGRect(x: 10, y: 10, width: 20, height: 20))

    if let imgBackArrow = UIImage(named: "icn_back_arrow") {
        imageView.image = imgBackArrow
    }
    view.addSubview(imageView)

    let backTap = UITapGestureRecognizer(target: self, action: #selector(backToMain))
    view?.addGestureRecognizer(backTap)

    let leftBarButtonItem = UIBarButtonItem(customView: view ?? UIView())
    self.navigationItem.leftBarButtonItem = leftBarButtonItem
}

@objc func backToMain() {
    self.navigationController?.popViewController(animated: true)
}
16
Booharin

Avoir un bouton dans la barre de navigation avec Image AND Text est assez difficile. Surtout après avoir introduit un nouveau casse-tête avec la position d'UIBarButtonItem dans iOS 11: iOS 11 - Position horizontale de UIBarButtonItem

Vous pouvez créer un bouton avec une image ou un bouton avec un texte, mais pas un bouton avec les deux. J'ai même essayé deux UIBarButtonItems ensemble, l'un avec une image et l'autre avec un texte - cela n'a toujours pas l'air beau et leur UIStackView n'est pas facilement accessible pour modification.

De façon inattendue, j'ai trouvé une solution simple et simple:

1) concevez le bouton sous forme de vue dans Interface Builder. Dans mon cas, il est dans la cible UIViewController et accessible via IBOutlet pour plus de simplicité.

2) définissez la contrainte d'espace de contour pour que l'image soit négative, vous pouvez également définir la couleur d'arrière-plan de la vue sur .clear.

 enter image description here

3) l'utiliser:

@IBOutlet var backButtonView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()

    let backButton = UIBarButtonItem(customView: self.backButtonView)
    self.backButtonView.heightAnchor.constraint(equalToConstant: 44).isActive = true // if you set more than you'll get "Unable to simultaneously..."
    self.backButtonView.widthAnchor.constraint(equalToConstant: 75).isActive = true
    self.navigationItem.leftBarButtonItem = backButton
}

C'est tout. Pas besoin d'utiliser l'astuce avec spacer négatif pour iOS 10 ou l'astuce avec imageInsets pour iOS 11 (qui ne fonctionne que si vous avez une image et ne fonctionne pas pour image + texte, BTW).

 enter image description here

8
Vitalii

Pour l'image du bouton de retour: 

  • Par ce tutorial : (mais n'a pas fonctionné pour moi)

    UINavigationBar.appearance().backIndicatorImage = UIImage(named: "imageName")
    
  • Mais cette pile réponse : (a travaillé pour moi)

    var backButtonImage = UIImage(named: "back-button-image")
    backButtonImage = backButtonImage?.stretchableImage(withLeftCapWidth: 15, topCapHeight: 30)
    UIBarButtonItem.appearance().setBackButtonBackgroundImage(backButtonImage, for: .normal, barMetrics: .default)
    

Et pour la police, supposons que vous souhaitiez que la police corresponde à toute la barre de navigation: (actuellement utilisée)

if let font = UIFont(name: "Avenir-Book", size: 22) {
  UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName: font]
}
5
Idan

Swift 3 

    extension UIViewController {

        func setBackButton(){
            let yourBackImage = UIImage(named: "backbutton")
            navigationController?.navigationBar.backIndicatorImage = yourBackImage
            navigationController?.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
        }

    }
2
Safad Funy

Il suffit de remplacer le backButton par un rightBarButtonItem personnalisé

let backImage = UIImage(named: "BackBtn")?.withRenderingMode(.alwaysOriginal)
    navigationItem.leftBarButtonItem = UIBarButtonItem(image: backImage, style: .plain, target: self, action: #selector(popnav))

    @objc func popnav() {
    self.navigationController?.popViewController(animated: true)
}
1
Mohamed Ali

Swift 4.2 Ajoutez cette fonction ViewController

func addNavigationBarButton(imageName:String,direction:direction){
    var image = UIImage(named: imageName)
    image = image?.withRenderingMode(.alwaysOriginal)
    switch direction {
    case .left:
       self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
    case .right:
       self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
    }
}

@objc func goBack() {
    navigationController?.popViewController(animated: true)
}

enum direction {
    case right
    case left
}

En utilisant, vous devriez utiliser ici

viewDidLoad () 

addNavigationBarButton(imageName: "ic_back", direction:.left)
0
ikbal

J'ai essayé tout ce qui précède et créé une image personnalisée sans changer le texte Le seul qui fonctionne pour moi provient de cette answer

let backBTN = UIBarButtonItem(image: UIImage(named: "Back"), 
                              style: .plain, 
                              target: navigationController, 
                              action: #selector(UINavigationController.popViewController(animated:)))
navigationItem.leftBarButtonItem = backBTN
navigationController?.interactivePopGestureRecognizer?.delegate = self
0
Mohamed Saleh