setBackButtonBackgroundImage not working - ios

I am simply trying to change the back button icon in the UINavigationBar to a custom image so it matches all the rest of the icons used, however I have approached this two different ways.
One setting the back image an mask image in the UINavigationController within the storyboard inspector to the image, which resulted in the image not being in line with the title or rightBarItem.
Another method I have tried is setBackButtonBackgroundImage within the ViewController file or appDelegate. However the following code;
let backImg: UIImage = UIImage(named: "Back")!
UIBarButtonItem.appearance().setBackButtonBackgroundImage(backImg, forState: .Normal, barMetrics: .Default)
But the result of this was far more weird, the image becomes stretched.
Can anyone help me out on why this is happening or give an alternate method to change the back icon in the UINavigationBar ?

let backImage = UIImage(named: "back_button_name")
UIBarButtonItem.appearance().setBackButtonBackgroundImage(backImage?.resizableImageWithCapInsets(UIEdgeInsetsMake(0, (backImage?.size.width)!-1, 0, 0)), forState: .Normal, barMetrics: .Default)

Swift 3.0
let backImage = UIImage(named: "arrow_left")
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage

Related

iOS 11-12 large title background image for large state

I am trying to set different colors for different navigation bar large title states. For base large title state(when it's large and not scrolled) bar should have grayColor(i am setting barTint color), but when the user scrolls content and bar is attached to top(goes to UIBarPosition.topAttached) it should have white color, so I am setting background image for .topAttached state, and because of that image my barTint color is ignored.
I've tried to set background image for all possible nav bar UIBarPosition's and UIBarMetrics, and for topAttached state image work's well, but for large state it never appeared. Example:
bar.setBackgroundImage(.pixel(color: UIColor.red), for: .any, barMetrics: .default)
bar.setBackgroundImage(.pixel(color: UIColor.green), for: .topAttached, barMetrics: .default)
bar.setBackgroundImage(.pixel(color: UIColor.blue), for: .bottom, barMetrics: .default)
bar.setBackgroundImage(.pixel(color: UIColor.purple), for: .top, barMetrics: .default)
Is there any way to make different colors for different large title states in iOS 11-12?
Finally found solution, works for iOS 11-12:
let observer = navBar.observe(\.frame, changeHandler: { (bar, frame) in
if navBar.frame.height <= 44 {
navBar.barTintColor = UIColor.lightGray
navBar.shadowImage = imageForShadow
}
else {
navBar.barTintColor = UIColor.white
navBar.shadowImage = UIImage()
}
})

How can I change the back button image in the navigation bar for iOS 13?

On the right, the first time and on the left, all the other times
Hello Guys,

I’m new so I hope that’s the way things goes around here !
Like y’all know, iOS 13 introduced UI changes. We have an app in production and I recently woke up (maybe a little too late haha) and as I compiled and launch it on a freshly updated iOS 13 device, that’s when I became aware there was some work to do ! 

I handled the dark mode by not enabling it, I handled my modals but there is one thing I can’t seem to make like iOS 12 and it’s my Navigation Bar UI.
We use a custom back button image and after fighting during several hours, I finally succeeded but it’s ok everytime except the first time. I will always have the default icon the first time, and then when I come back to the same controller, it’s okay.
Here is a photo (at the beginning of the question) so you can understand and also my code !
I know it’s possible to use Appearance for specific VC with « whenContained » but I can’t seem to figure it out cause it’s all in navigation controller and I don’t know how to differentiate them.
fileprivate func navigationBarWithBackgroundColor(_ backgroundColor: UIColor, TintColor tintColor: UIColor, displayBackButtonIfNeeded: Bool, BackImage imageName:String, displayShadowBar: Bool = false) {
let backButtonImage = UIImage(named: imageName)
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.backgroundColor = backgroundColor
appearance.titleTextAttributes = [.foregroundColor: tintColor]
appearance.setBackIndicatorImage(backButtonImage, transitionMaskImage: backButtonImage)
appearance.shadowImage = displayShadowBar ? UIImage(named:"") : UIImage()
let back = UIBarButtonItemAppearance()
// hide back button text
back.normal.titleTextAttributes = [.foregroundColor: UIColor.clear]
appearance.backButtonAppearance = back
navigationController?.navigationBar.tintColor = tintColor
navigationController?.navigationBar.standardAppearance = appearance
navigationController?.navigationBar.compactAppearance = appearance
navigationController?.navigationBar.scrollEdgeAppearance = appearance
} else {
if displayBackButtonIfNeeded {
self.navigationController?.navigationBar.backIndicatorImage = backButtonImage
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backButtonImage
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItem.Style.plain, target: nil, action: nil)
} else {
self.navigationItem.setHidesBackButton(true, animated: false)
}
self.navigationController?.navigationBar.barTintColor = backgroundColor
self.navigationController?.navigationBar.tintColor = tintColor
self.navigationController?.navigationBar.setBackgroundImage(UIImage(named:""), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = displayShadowBar ? UIImage(named:"") : UIImage()
}
}
I’m basically become crazy here and I assume I’m missing something very obvious so if you guys have any hints or clues except apple documentation, feel free to share :)

Thanks in advance !
In iOS 13 you can set up back button image and transition mask image only by the function
func setBackIndicatorImage(UIImage?, transitionMaskImage: UIImage?)
And here is an example
standartAppearence.setBackIndicatorImage(#imageLiteral(resourceName: "backButton"), transitionMaskImage: #imageLiteral(resourceName: "backButton"))

UINavigation set back button image instead of the <Back text Swift 2.0

I am trying to change the Back button within the UINavigationController. This is what I tried so far and the output:
1
Code within the ViewDidLoad
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "navBarBackButton")
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "navBarBackButton")
self.navigationItem.backBarButtonItem?.image = UIImage(named: "navBarBackButton")
Output:
I tried to add the below but id didn't help:
self.navigationItem.backBarButtonItem = UIBarButtonItem(title:"", style:.Plain, target:nil, action:nil)
2
Code within the AppDelegate
let backImg: UIImage = UIImage(named: "navBarBackButton")!
UIBarButtonItem.appearance().setBackButtonBackgroundImage(backImg, forState: .Normal, barMetrics: .Default)
Output:
3
I tried to add the back button in Storyboard but nothing changed
4 - Thanks to sanandiya vipul. Still need it to be instead of the 'Back'. This only deletes the 'Back but keeps the image lower right side instead of the entire '
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -80.0), forBarMetrics: .Default)
This is the output:
This is the result I am hoping to achieve
Below Code add your ViewDidLoad method. its work for you fine.
for Swift
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -80.0), forBarMetrics: .Default)
for Objective-c
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0,- 80.f) forBarMetrics:UIBarMetricsDefault];
Swift 4 version
Set Back title text color to clear
let barButtonItemAppearance = UIBarButtonItem.appearance()
barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .highlighted)
Just added UIBarButtonItem and linked it to action.
#IBAction func backTapped(sender: AnyObject) {
self.navigationController?.popViewControllerAnimated(true)
}
Swift 5 version
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffset(horizontal: 0, vertical: -80.0), for: .default)

UIBarButtonItem: Image offsets

I am trying to create custom back bar button item using image. I've done it this way:
let image = UIImage(named: "Back")
self.navigationBar.backIndicatorImage = image
self.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "Back")
self.navigationBar.tintColor = UIColor.blackColor()
But here's result:
As you can see, it should be moved a little down and a little right. I tried to add offset to image this way:
self.navigationBar.backIndicatorImage = image?.imageWithAlignmentRectInsets(UIEdgeInsetsMake(10, 40, 0, 0))
But it does not work, the same. Any ideas?
Although, I feel, there is a scope to move title bit up to match with back button, you can move nav bar button down by:
UINavigationBar.appearance().setTitleVerticalPositionAdjustment(5.0, forBarMetrics: UIBarMetrics.Default)
To move it to right, try adding a flexible space, something like:
let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)

Changing navigation bar back button image size globally

Currently I am using the following code to produce a custom back button image for my navbars:
appearance.backIndicatorImage = UIImage(named: "arrow-back")
appearance.backIndicatorTransitionMaskImage = UIImage(named: "arrow-back")
Unfortunately my image is large so it looks better on retina devices, and this method just displays the default size. Any way to shrink it down to get it fitting nicely?
My code will help you
let btnImg = UIImage(named: "Location_OnMap")
let btn = UIBarButtonItem(image: btnImg, style: .Plain, target: self, action: "doSomthing")
self.navigationItem.leftBarButtonItem = btn

Resources