Change ViewController's Back Button Image for all screens - ios

I have this below code that changes the back button image on next screen.
I have 30 screens in my app and i want back button to be same across all 30 screens. Is it possible that I don't copy paste this code on all 30 screens and just write it once and rather reuse it across 30 screens.
Also, the code attached with back button should work fine on all screens when i reuse it
I am using iOS 8 and Xcode 6.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let backButtonImage: UIImage = UIImage(named: "back")!
var backBarItem: UIBarButtonItem = UIBarButtonItem(image: backButtonImage, style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method"))
segue.destinationViewController.navigationItem.leftBarButtonItem = backBarItem;
}
func method() {
self.navigationController?.popViewControllerAnimated(true)
}

You can change it globally
UINavigationBar.appearance().backIndicatorImage = UIImage(named: "custom-back")
UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(named: "custom-back")
Or per navigation controller.
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.backIndicatorImage = UIImage(named: "custom-back")
navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "custom-back")
}
Full detail here https://sarunw.com/posts/how-to-change-back-button-image/

To general change the appearance of UI-Elements in iOS look at UIAppearance. This way you can set it once and it will be everywhere in your app.
I would recommend setting it in the AppDelegate application:didFinishLaunchingWithOptions:.
Try this:
let backImg: UIImage = UIImage(named: "back")!
UIBarButtonItem.appearance().setBackButtonBackgroundImage(backImg, forState: .Normal, barMetrics: .Default)

I only have one navigation Controller in my app, so this may or may not be helpful. But, I created a subclass of UINavigationController. Then in this subclass, I override the pushViewController method:
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
let pushingVC = viewControllers[viewControllers.count - 1]
let backItem = UIBarButtonItem()
backItem.title = ""
pushingVC.navigationItem.backBarButtonItem = backItem
super.pushViewController(viewController, animated: animated)
}
This, makes it so every time a viewController is pushed, from my customNavigationController, it uses the custom back button for every view. You have to make sure you change your UINavigationControllers type to your custom Subclass. But, this works for me in Swift 3.0.

You could use appearance()
Swift
let backImage = UIImage(named: "back")
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor:
UIColor.white], for: .normal)
UIBarButtonItem.appearance().tintColor = UIColor.green

I'm not quite sure what you wanted, so I'll answer most of what I think you could want for your sake and anyone looking at this in the future.
First: You want a back button similar to those on default apple apps. To do so, you need to a) get a reference to the destination scene and it's view controller. I will assume you have done so and set it equal to controller for future reference. b) You need to set the left bar button item. Set it with:
controller.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Insert Title Here!!", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
Place all of this in prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) (you will also find the destination scene with this, likely with segue.destinationViewController
Second: You want to use an image named "Back" for all items. If so, repeat step a) above, and insert this handy bit of code:
UIBarButtonItem(image: "Back", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
I also know you want to not have to copy it, but it's not as if this is that computer intensive anyways and it's probably simplest.
Third: You're smart and don't hate advances in programming so you want to use a storyboard. If so, simply drag in a Navigation Bar from the object menu, add a navigation item, and copy it to all of your scenes. If your scenes are linked to custom classes, then super happy fun time good news, you can simply link the navigation item to your custom class through an IBAction and use that function to do all the fancy coding your heart could ever desire.
Fourth: You really, really don't want to copy anything even if it's not that hard. If so, you can subclass a UIViewController with your own custom class, add the code I mentioned above, and then subclass all your future UIView classes as this. To be honest, I'm not entirely sure this would work and it seems unnecessarily laborious, but it's up to you.
I'm a bit tired right now so sorry for all the things I'm finding funny, but I hope I helped, and please tell me if I missed your point entirely and I can try and think of a solution.

Related

Set a default back button on a ViewController

short: I don´t understand how to programmatically add the default back button.
long: I have been asked to write an iOS app, without any previous experience I decided
to follow the advices and code given by Nicola Zaghini.
In the code given along with the article, I really don´t understand
where does the back button come from.
The app has three screens
one to choose a city (folder WeatherLocation)
one that displays all
cities that have been already choosen (folder WeatherList)
one that
displays the weather for a city clicked in the list (folder
WeatherDetail)
There is + button for WeatherLocation:
This button is added in the code but I can not find where
and how is coded the back button in WeatherDetails (see above), and how is coded the action to do when one click the back button.
I search the web and found how to set a button in the NavigationBar:
let leftBarButtonItem: UIBarButtonItem = {
let barButtonItem = UIBarButtonItem(title: "Left Item", style: .plain, target: self, action: nil)
barButtonItem.tintColor = UIColor.red
return barButtonItem
}()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.leftBarButtonItem = leftBarButtonItem
}
I also found that there is a backBarButtonItem
but I could not find how to properly use this property.
Moreover in the code of Nicola Zaghini there is nothing like backBarButtonItem to enable the
back button, neither in the xib and storyboard.
Can someone give me some hints about on how to set the back button ?
Thanks a lot!!
In the code of Nicola Zaghini the secret to have a default back button resides (for example) in the function navigateToWeatherDetail in the class WeatherListDefaultRouter where the new ViewController is pushed on a NavigationController:
func navigateToWeatherDetail(withLocation location: Location) {
if let weatherDetailVC = self.weatherDetailBuilder()?.buildWeatherDetailModule(withLocation: location) {
self.viewController?.navigationController?.pushViewController(weatherDetailVC, animated: true)
}
}

iOS: Back button label is cut off with custom font

I'm using a custom font for the navigationItem; When I segue to another view controller the back button on the newly presented view controller is cut off on the left side. I have tried setTitlePositionAdjustment(_ adjustment: UIOffset, for barMetrics: UIBarMetrics) on the first view controller, before doing segue but it didn't displace the button:
And
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Show Contents" {
if let viewController = segue.destination as? ContentsTableViewController {
viewController.navigationItem.backBarButtonItem?.setTitlePositionAdjustment(UIOffsetMake(10, 0), for: .default)
}
}
}
Using this code:
override func viewDidLoad() {
super.viewDidLoad()
let backBarButtonItem = UIBarButtonItem(title: "خانه", style: .plain, target: nil, action: nil)
backBarButtonItem.setTitleTextAttributes([.font : UIFont(name: "B Koodak", size: 32)!], for: .normal)
navigationItem.backBarButtonItem = backBarButtonItem
}
I get the following:
I encountered this issue when was using a custom font and I was hiding the navigation bar in the parent view and showing it in child views (in viewWillAppear(_:)). Figuring that something in this action was causing the button label to get drawn too narrow, I tried calling various UIKit redrawing methods on the navigation bar (setNeedsLayout() & setNeedsDisplay()) in the child view controllers' viewDidLoad() methods, but to no avail. I was able to get the label to draw properly by making the font size smaller, as the OP wrote.
I was eventually able to get it to draw properly at the correct size by manually setting the backBarButtonItem property to a new instance of UIBarButtonItem with "Back" as the title (in my parent view controller). This is possibly why it worked in the accepted answer. This seems to be a bug in UIKit, as I wouldn't think that hiding and showing the nav bar would cause this behavior.

How to customize the navigation back symbol and navigation back text?

This is the back icon and back text now:
But if I want my navigation back like this:
I have tried to set the back to my want icon image:
But it useless.
You can hide back button text in many ways.Try this simple approach.
Step1: Goto your mainstoryBoard and click navigationBar.
Step 2: Goto Attributes Inspector under Navigation Item add a BLANK SPACE in Back Button
Step 3: If you want to change backButton text method is pretty much the same.
Update 1: If you want to use an image as a back button check this link
Update 2:
Method 2: Using custom image as a back button.
Paste below code into your detailVC and set image for your back Button.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
title = "Detail VC"
let customButton = UIBarButtonItem(image: UIImage(named: "back"), style: .plain, target: self, action: #selector(backButtonTapped)) //
self.navigationItem.leftBarButtonItem = customButton
}
func backButtonTapped() {
_ = navigationController?.popToRootViewController(animated: true)
}
I am setting back button image in assets catalogue with the 32pixel size.I am not sure about the asset image size.Check with apple doc about the size class.
Output:
Create a new UIBarButton and add it the navigationItem.leftBarButton.
let backButton = UIBarButtonItem(image: UIImage(named:"yourImage"), style: .plain, target: self, action: #selector(yourBackMethod(sender:))
navigationItem.leftBarButtonItem = = backButton
#objc internal func yourBackMethod(sender: AnyObject) {
navigationController.popViewController()
}
Hope this helps.

How change the back button to a custom image in Swift2

Hi,
I'm trying to figure out how to change the back button to a custom image on all ViewControllers. I read though a few questions regarding to this solution, but it was mostly outdated.
I want to change < Back to a stock image I have
I was able to disable to hide the back but that's not my goal my goal is to change the default image to a custom one, I added the custom image to the images.xcassets and that didn't work also I tried to set the System Item to Custom and under Bar Item I selected my image which is image.png, but still didn't work, can someone help me approach this solution? Thanks.
override func viewDidLoad() {
let image: UIImage = UIImage(named: "images")!
self.navigationController?.navigationItem.backBarButtonItem?.image = image
}
override func viewDidAppear(animated: Bool) {
// let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: navigationController, action: nil)
// navigationItem.leftBarButtonItem = backButton
self.navigationItem.setHidesBackButton(false, animated: false)
}
Instead of doing that you can create your own custom button and assign it to leftBarButtonItem. Try this out
var backBtn = UIBarButtonItem()
let image: UIImage = UIImage(named: "images")!
backBtn.image = image
//set other properties for your button
//set traget and action
self.navigationItem.leftBarButtonItem = backBtn
You can just pop the current view controller in action of the back button.
You can add this in AppDelegate
UIBarButtonItem.appearance().setBackButtonBackgroundImage(UIImage(named: name), forState: .Normal, barMetrics: .Default)
This will set back button through out the app

Change back button title when pushing a UIViewController on UITableViewController

View hierarchy:
UINavigationController
->UITableViewController(1)
->UITableViewController(2)
->UIViewController(3)
In 1 and 2 I have this code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
self.navigationItem.backBarButtonItem?.title = ""
}
It should override the back button title of the next view controller pushed on the current view controller. It works from 1 -> 2. But it does not work for 2 -> 3. In 3 the back button title has a title, the name of the previous UITableViewController.
Any ideas whats wrong? I am using swift, xcode6.1 and iOS8.1
You could init a new back button with no title. Just put this in the viewDidLoad() of each view controller.
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
--
I am going to extend this answer with my experience. So I managed to remove the title of the back button to display just the back arrow. In storyboard you have to select the navigation item that displays the title inside the navigation bar of the previous view controller. There is a property called Back Button. Just enter a space and save. It will remove the back button title.
Update
UIBarButtonItemStyle.Bordered was deprecated in iOS 8.0. Use UIBarButtonItemStyle.Plain instead.
thanks,
if you want using customer back button image, you can use this
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: “backImage”)
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: “ backImage”)
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: “”, style: UIBarButtonItemStyle.Plain, target: nil, action: nil)

Resources