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)
}
}
Related
I'm trying to add a simple "Done" button to my UIPickerView programmatically, without using storyboards.
When I try to add toolBar as a subview of the UIPickerView, the toolbar doesn't even show up and I get some constraint related errors.
Any idea on how I can add the button to the PickerView?
Here is a snippet of my code:
var timerImage = UIButton()
var timer = Timer()
var timerDisplayed = 0
let image1 = UIImage(named: "stopwatch")
let timePicker = UIPickerView()
let timeSelect : [String] = ["300","240","180","120","90","60","45","30","15"]
let toolBar = UIToolbar()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ThirdViewController.dismissKeyboard))
func pickerViewConstraints(){
timePicker.anchor(top: nil, leading: view.safeAreaLayoutGuide.leadingAnchor, bottom: view.safeAreaLayoutGuide.bottomAnchor, trailing: view.safeAreaLayoutGuide.trailingAnchor)
}
#objc func timeClock(){
toolBar.setItems([doneButton], animated: true)
toolBar.sizeToFit()
toolBar.isTranslucent = false
toolBar.isUserInteractionEnabled = true
toolBar.barStyle = .default
view.addSubview(timePicker)
timePicker.addSubview(toolBar)
pickerViewConstraints()
timePicker.backgroundColor = .white
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.Action), userInfo: nil, repeats: true)
self.timerImage.setImage(nil, for: .normal)
}
}
No, you don't need to add constraints. It can be like :
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(title: buttonTitle, style: .done, target: self, action: #selector(doneButtonAction))
let cancelButton = UIBarButtonItem(title: cancelTitle, style: .plain, target: self, action: #selector(cancelButtonAction))
let barAccessory = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 44))
barAccessory.barStyle = .default
barAccessory.isTranslucent = true
barAccessory.barTintColor = .blue
barAccessory.setItems([cancelButton, space, doneButton], animated: false)
picker.addSubview(barAccessory)
self.view.bringSubviewToFront(picker)
Hope it helps...
You need to set a delegate of type UIPickerViewDelegate to your picker view. In this delegate, implement the delegate method pickerView:viewForRow:forComponent:reusingView
to provide your custom view for the picker item.
For the custom view you provide, you can design it however you want, including adding the button.
It looks like it's just a few minor issues here. Here's how I've done it prior:
override func viewDidLoad() {
super.viewDidLoad()
createToolbar()
}
// Toolbar for "done"
func createToolbar() {
let toolBar = UIToolbar()
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(PageOneViewController.dismissKeyboard))
toolBar.setItems([doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
// Makes toolbar apply to text fields
educationText.inputAccessoryView = toolBar
politicalText.inputAccessoryView = toolBar
drinkingText.inputAccessoryView = toolBar
heightText.inputAccessoryView = toolBar
schoolInput.inputAccessoryView = toolBar
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
It seems like you haven't technically "called" the toolbar / done button, unless I'm just not seeing that part of the code. Also I've nested the "done" code inside of the function.
If you're using text fields then you should be able to follow to "educationText.inputAccessoryView = toolBar" format to apply all of the code above to each text field (education, politics, drinking, etc). I hope this helps! Good luck.
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!) {
}
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]
I'm programmatically adding a toolbar to a UIPickerView so that I can have a "Done" button, and I want to make the UIToolBar black and the bar items white. The doc says that if you want an opaque UIToolBar, you have to set its translucency to false and set barStyle to black. I've done this and the UIToolBar remains white.
private func pickerViewSetup() {
let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.dataSource = self
pickerView.backgroundColor = .whiteColor()
pickerView.showsSelectionIndicator = true
let toolBar = UIToolbar()
toolBar.translucent = false
toolBar.barStyle = .Black
let doneButton = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: "donePicker")
doneButton.tintColor = UIColor.whiteColor()
let flexibleSpaceItem = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: self, action: "Flexible Space")
toolBar.setItems([flexibleSpaceItem, doneButton], animated: false)
toolBar.userInteractionEnabled = true
pickerTextField.inputView = pickerView
pickerTextField.inputAccessoryView = toolBar
}
Thanks u84six's answer. You can do like this:
toolBar.tintColor = UIColor.whiteColor()//"Done" button colour
toolBar.barTintColor = UIColor.blackColor()// bar background colour
toolBar.sizeToFit()// Very important, the barTintColor will not work without this
All I needed to do is add the call toolBar.sizeToFit() and that fixed all the color issues. Here's the complete working code:
private func pickerViewSetup() {
let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.dataSource = self
pickerView.backgroundColor = .whiteColor()
pickerView.showsSelectionIndicator = true
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.Black
toolBar.tintColor = UIColor.whiteColor()
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: "donePicker")
let flexibleSpaceItem = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: self, action: "Flexible Space")
toolBar.setItems([flexibleSpaceItem, doneButton], animated: false)
toolBar.userInteractionEnabled = true
pickerTextField.inputView = pickerView
pickerTextField.inputAccessoryView = toolBar
}
This is not enough. Add
toolBar.backgroundColor = UIColor.BlackColor();
The toolBar is not of the desired color because toolBar.backgroundColor is not properly set. Set it to BlackColor with
toolBar.backgroundColor = UIColor.BlackColor()
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 = ""