Back Button Image - what is it called in Swift? - swift

I am trying to use Swift's internal back button image.
I have asked this question before and got the technically correct answer that it inherits it from the previous View, BUT if I insert this code you can control the back button on the current View.
// Takeover Back Button
self.navigationItem.hidesBackButton = false
let newBackButton = UIBarButtonItem(title: "<", style: .Plain, target: self, action: "segueBack")
navigationItem.leftBarButtonItem = newBackButton
That gives me a <, "ABC" would give me ABC etc but how do I trigger Swift to put up it's internal Back Button image. The code below doesn't work but I would have thought is along the right lines.
let backImg: UIImage = UIImage(named: "BACK_BUTTON_DEFAULT_ICON")!
navigationItem.leftBarButtonItem!.setBackgroundImage(backImg, forState: .Normal, barMetrics: .Default)
Has anyone worked out how to do this?

Try to add custom view as back button like as
var backButton = UIButton(frame: CGRectMake(0, 0, 70.0, 70.0))
var backImage = UIImage(named: "backBtn")
backButton.setImage(backImage, forState: UIControlState.Normal)
backButton.titleEdgeInsets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 0.0)
backButton.setTitle("Back", forState: UIControlState.Normal)
backButton.addTarget(self, action: "buttonPressed", forControlEvents: UIControlEvents.TouchUpInside)
var backBarButton = UIBarButtonItem(customView: backButton)
var spacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
spacer.width = -15
self.navigationItem.leftBarButtonItems = [spacer,backBarButton]
It will look same as iOS back button

I struggled with this question for a while. Finally I got the back image with the following code:
let backImage = navigationController?.navigationBar.subviews[2].subviews[0].subviews[0].subviews[0] as! UIImageView).image
Before run the code above, make sure the back button is showing. Then you can save backImage to anywhere you want.
Here is the backImage I got.

Here is my solution:
override func viewDidLoad() {
...
let buttonBack = UIBarButtonItem(image: UIImage(named: "backButton"), style: .plain, target: self, action: #selector(buttonSavePressed(_:)))
self.navigationItem.leftBarButtonItem = buttonBack
let backButton = UIButton(frame: CGRect(x: 0, y: 0, width: 24.0, height: 24.0))
let backImage = UIImage(named: "backButton")
backButton.setImage(backImage, for: .normal)
backButton.setTitle("Back", for:.normal)
if #available(iOS 13.0, *) {
backButton.setTitleColor(.link, for: .normal)
} else {
backButton.setTitleColor(.blue, for: .normal)
}
backButton.addTarget(self, action:#selector(buttonSavePressed(_:)), for: .touchUpInside)
let backBarButton = UIBarButtonItem(customView: backButton)
let spacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
spacer.width = -15
self.navigationItem.leftBarButtonItems = [spacer,backBarButton]
}
#objc func buttonBackPressed(_ sender: Any) {
...
}

If you want to get the default back button image, the arrow is a class of type _UINavigationBarBackIndicatorView.
Here follows the hack,
UIImage *imgViewBack ;
for (UIView *view in self.navigationController.navigationBar.subviews) {
// The arrow is a class of type _UINavigationBarBackIndicatorView. This is not any of the private methods, so I think
// this is fine for the AppStore...
if ([NSStringFromClass([view class]) isEqualToString:#"_UINavigationBarBackIndicatorView"]) {
// Set the image from the Default BackBtn Imageview
UIImageView *imgView = (UIImageView *) view;
if(imgView){
imgViewBack = imgView.image ;
}
}
}

Try this to replace the back button image:
let back_image = UIImage(named: "btn_back")
self.navigationBar.backIndicatorImage = back_image
self.navigationBar.backIndicatorTransitionMaskImage = back_image
If you don't like to have the "Back" title you can add this too:
self.navigationBar.topItem?.title = ""

Related

titleView of Navigation item moved to the left?

I have an app with a left (hamburger) navigationItem.leftBarButtonItem and we've set the titleView to the logo of the company. The problem is that they want the logo next to the hamburger. The hamburger button is set in the Storyboard's ViewController and the logo is programmatically, like this:
let logo = UIImage(named: "logo.png")
let imageView = UIImageView(image:logo)
imageView.frame = CGRect(x: 0, y: 0, width: 120, height: 60)
navigationItem.titleView = imageView
Is there a way to move it to the left?
UPDATE:
Regarding the suggestions to use leftBarButtonItems
I've done this in another UIViewController and the result wasn't as I expected it to be.
Here's the code:
let logo = UIImage(named: "logo")!
let karambaButton = UIBarButtonItem(image: logo, style: .plain, target: self, action: nil)
let backBTN = UIBarButtonItem(image: UIImage(named: "back"), style: .plain, target: navigationController, action: #selector(UINavigationController.popViewController(animated:)))
navigationItem.leftBarButtonItems = [backBTN, logoButton]
And here's the result of it:
(The dark block is the image, I had to cover it up because it's a client)
You can set multiple left bar button items by acessing:
navigationItem.leftBarButtonItems = [barItem1, barItem2]
Same with the right side. :)
You can also set auto layout programmatically.
imageView.translatesAutoresizingMaskIntoConstraints = false
let horizontalConstraint = imageView.leadingAnchor.constraint(equalTo: hamburgerButton.trailingAnchor, constant: 10)
let verticalConstraint = newView.centerYAnchor.constraint(equalTo: hamburgerButton.centerYAnchor)
let widthConstraint = newView.widthAnchor.constraint(equalToConstant: 120)
let heightConstraint = newView.heightAnchor.constraint(equalToConstant: 120)
imageView.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
UINavigationItem has a property named leftBarButtonItems.
Put your logo imageView into the customView property of a UIBarItem and size it correctly and you should be all set. Just add it to the the array along with the hamburger button.
edited to add -- try using a custom view, that is:
if let logo = UIImage(named: "logo") {
let imageView = UIImageView(image:logo)
let karambaButton = UIBarButtonItem(customView: imageView)
let backBTN = UIBarButtonItem(image: UIImage(named: "back"), style: .plain, target: navigationController,
action: #selector(UINavigationController.popViewController(animated:)))
navigationItem.leftBarButtonItems = [backBTN, logoButton]
}

Swift hide back button

I need to hide back button and paste another button
self.navigationItem.setHidesBackButton(true, animated: false)
self.navigationItem.hidesBackButton = true
self.navigationController?.navigationItem.hidesBackButton = true
self.navigationController?.navigationBar.topItem?.hidesBackButton = true
self.tabBarController?.navigationController?.navigationItem.hidesBackButton = true
self.tabBarController?.navigationController?.navigationItem.setHidesBackButton(true, animated: false)
self.tabBarController?.navigationItem.hidesBackButton = true
let backButton1 = UIBarButtonItem (title: "Button", style: .plain, target: self, action: #selector(GoToBack))
self.navigationItem.leftBarButtonItem = backButton1
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(GoToBack))
self.tabBarController?.navigationItem.setLeftBarButtonItems([backButton1], animated: true)
but this code didnt work, back button dont hided or replaced to another button
how can i solve this problem ?
show this vc like this
self.navigationController?.pushViewController(viewcontroller, animated: true)
First, Create BaseViewController in your project and set backButton hide code and add custom back button code in viewDidLoad.
After that, all the controller of your project should inherit from BaseViewController so new back button enables for all controller.
BaseViewContorller
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.hidesBackButton = true
self.setBackButton()// Set Custom back button
}
Set Custom BackButton Code
//Add Custom Back Button
fileprivate func setBackButton() {
let button = UIButton(type: UIButton.ButtonType.custom) as UIButton
button.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .center
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: -10, bottom: 0, right: 0)
button.setImage(UIImage(named: "backButton.png"), for: .normal)
button.addTarget(self, action: #selector(btnBackActionHandler(_:)), for:.touchUpInside)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: button)
}
#objc func btnBackActionHandler(_ sender : AnyObject) {
self.navigationController?.popViewController(animated: true)
}
Use the below code
self.navigationItem.setHidesBackButton(true, animated:true);
addNavButtons()
//MARK:- NAVIGATION BUTTONS
func addNavButtons(){
let btn_back = UIButton(type: .custom)
btn_back.setImage(UIImage(named: "icon_back"), for: .normal)
btn_back.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
btn_back.addTarget(self, action: #selector(goBack), for: .touchUpInside)
btn_back.imageView?.contentMode = UIViewContentMode.scaleAspectFit
let menuitem1 = UIBarButtonItem(customView: btn_back)
self.navigationItem.setLeftBarButtonItems([menuitem1], animated: true)
let btn_search = UIButton(type: .custom)
btn_search.setImage(UIImage(named: "searchby_icon"), for: .normal)
btn_search.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
btn_search.addTarget(self, action: #selector(SearchButtonClick), for: .touchUpInside)
btn_search.imageView?.contentMode = UIViewContentMode.scaleAspectFit
let menuitem2 = UIBarButtonItem(customView: btn_search)
self.navigationItem.setRightBarButtonItems([menuitem2], animated: true)
}
#objc func goBack(sender:UIButton!) {
_ = navigationController?.popViewController(animated: true)
}
#objc func SearchButtonClick(sender:UIButton!) {
}

iOS: adding buttons to Toolbar programmatically

I need to create Toolbar and add buttons programmatically. I will have different sets of buttons for diferent screens.
That's easy.
Also, I need to center those buttons. They should have equal space between them.
And also I need that all those buttons separate screen width only between themselfs. Like, I have 5 buttons, total screen width is 300, so each button will have width 60. I am not sure how to do that, i tried dirrenrt things but they wasn't centered or hadn't such width. Any ideas how to do that?
class OptionsView: UIView {
#IBOutlet weak var toolbar: UIToolbar!
var width: CGFloat {
return 0//UIScreen.main.bounds.width/5 //was trying to calculate width , but it did not work
}
override func awakeFromNib() {
super.awakeFromNib()
toolbar.isTranslucent = true
toolbar.setBackgroundImage(UIImage(), forToolbarPosition: UIBarPosition.any, barMetrics: UIBarMetrics.default)
toolbar.setShadowImage(UIImage(), forToolbarPosition: UIBarPosition.any)
toolbar.barTintColor = .white
backgroundColor = .clear
}
func addAirPlay(target: Any?, action: Selector) {
let normalImage = UIImage(named: "player-airplay")
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: width, height: 100)
button.setImage(normalImage, for: UIControlState())
button.addTarget(target, action: action, for: .touchUpInside)
let item = UIBarButtonItem(customView: button)
//item.width = width //was trying to play with that
var items = toolbar.items
items?.append(item)
toolbar.items = items
toolbar.reload()
}
func addOrientation(target: Any?, action: Selector) {
let button = UIButton(type: .custom)
button.tag = orientationTag
button.frame = CGRect(x: 0, y: 0, width: width, height: 100)
button.addTarget(target, action: action, for: .touchUpInside)
let item = UIBarButtonItem(customView: button)
//item.width = width
var items = toolbar.items
items?.append(item)
toolbar.items = items
toolbar.reload()
reloadOrientation()
}
func addFlexibleSpace() {
let item = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
var items = toolbar.items
items?.append(item)
toolbar.items = items
toolbar.reload()
}
Creating:
optionsView = OptionsView.loadFromNib()
playerView.addSubview(optionsView)
optionsView.snp.makeConstraints { (make) in
make.leading.trailing.top.bottom.equalTo(self.optionsPlaceholderView)
}
// optionsView.addFlexibleSpace() //was trying that as well
optionsView.addAirPlay(target: self, action: #selector(airplayButtonAction(_:)))
optionsView.addFlexibleSpace()
optionsView.addOrientation(target: self, action: #selector(orientationButtonAction(_:)))
optionsView.addFlexibleSpace()
optionsView.addFave(target: self, action: #selector(faveButtonAction(_:)))
optionsView.addFlexibleSpace()
optionsView.addExtra(target: self, action: #selector(showExtraButtonAction(_:)))
optionsView.addFlexibleSpace()
optionsView.addScenes(target: self, action: #selector(sceneButtonAction(_:)))
// optionsView.addFlexibleSpace()

Evenly space UIToolbar buttons in inputAccessoryView

In the following code I have three buttons that show when an inputField is tapped. Right now the buttons show but all of them are shifted to the left and what I would like to do is have them evenly space and keep them like that regardless of what phone size they are viewed on.
How can I evenly space the buttons in a UIToolbar?
CODE:
override func viewDidLoad() {
super.viewDidLoad()
addButtonsToKeyboard()
}
// Reusable Button
func configurButton(button:UIButton) {
button.backgroundColor = UIColor.whiteColor()
button.layer.cornerRadius = 5
button.layer.borderWidth = 1.0
button.layer.borderColor = UIColor.blueColor().CGColor
button.setTitleColor(UIColor.lightGrayColor(), forState: .Normal)
button.setTitleColor(UIColor.blueColor(), forState: .Highlighted)
button.frame = CGRect(x:0, y:0, width:50, height:35)
button.addTarget(self, action: #selector(customKeyPressed), forControlEvents: UIControlEvents.TouchUpInside)
}
func addButtonsToKeyboard(){
// First button
let button1 = UIButton()
button1.setTitle("Btn 1", forState: .Normal)
configureButton(button1)
let barButton1 = UIBarButtonItem()
barButton1.customView = button1
// Second button
let button2 = UIButton()
button2.setTitle("Btn 2", forState: .Normal)
configureButton(button2)
let barButton2 = UIBarButtonItem()
barButton2.customView = button2
// Third button
let button3 = UIButton()
button3.setTitle("Btn 3", forState: .Normal)
configureButton(button3)
let barButton3 = UIBarButtonItem()
barButton3.customView = button3
/**
* UIToolbar.
*/
let toolBar = UIToolbar()
toolBar.tintColor = UIColor.redColor()
toolBar.barTintColor = UIColor.lightGrayColor()
toolBar.items = [barButton1, barButton2, barButton3]
toolBar.sizeToFit()
myInputField.inputAccessoryView = toolBar
}
func customKeyPressed(sender: UIButton){
// do something
}
CURRENT:
AFTER:
Very simple, you just need to add a flexible bar button item between each button. See the following:
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
toolbar.items = [barButton1, space, barButton2, space, barButton3]

hide backbutton embedded UINavigationController swift3

I am using embedded navigationController with Xcode8 and Swift3, i could have done some changes like transparent background etc but can not hide backbutton or change its title
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
How can i make the backbutton custom in navigation bar?
thanks
You could write this code under viewWillAppear:
override func viewWillAppear(_ animated: Bool)
{
super.viewWillAppear(animated)
self.navigationItem.hidesBackButton = true
}
If you want to add an image you can do:
let leftButton: UIBarButtonItem = UIBarButtonItem(image: buttonImage, style: UIBarButtonItemStyle.plain, target: self, action:#selector(ViewController.leftButtonPress(sender:)))
navigationItem.leftBarButtonItem = leftButton
Design a custom UIButton and replace the default NavigationBar BackBarButtonItem with it.
func customBackButton() {
let leftButton = UIButton(type: UIButtonType.Custom)
leftButton.frame = CGRectMake(0, 0, 36, 36)
leftButton.clipsToBounds = true
leftButton.setTitle("yourTitle", forState: .Normal) //set back button title
leftButton.setImage(UIImage(named: "yourBackButton.png"), forState: .Normal) // add custom image
leftButton.addTarget(self, action: #selector(self.onBackButton_Clicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
let leftBarButton = UIBarButtonItem()
leftBarButton.customView = leftButton
self.navigationItem.leftBarButtonItem = leftBarButton
}
func onBackButton_Clicked(sender: UIButton)
{
if(webview.canGoBack) {
webview.goBack()
}
else {
self.navigationController.popViewController(animated: true)
}
}