UIBarButtonItem programmatically change color - swift

I have this left UIBarButtonItem that performs like a switch, so I would like to make it gray when its off and the normal tint color when its on but I can't figure out how
Here is the code used to assign the buttons:
doneHomeworksButton = UIBarButtonItem(image: doneHomeworksButtonImage, style: .plain, target: self, action: #selector(doneHomeworksClicked))
addButton = UIBarButtonItem(image: plusButtonImage, style: .plain, target: self, action: #selector(plusButtonClicked))
self.navigationItem.rightBarButtonItem = addButton
self.navigationItem.leftBarButtonItem = doneHomeworksButton
This is the simulator (I want to change the left button)

This is the way, I use text instead of icon. you can user FM symbols of fontawesome or any other. And also you can change the image when button click
class ViewController: UIViewController{
var btnTick:UIBarButtonItem?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
btnTick = UIBarButtonItem(title: "2", style: .plain, target: self, action: #selector(didClickedBtn(_ :)))
btnTick?.tintColor = .blue
navigationItem.leftBarButtonItem = btnTick
}
#objc func didClickedBtn(_ sender : UIBarButtonItem){
sender.tintColor = .red
view.layoutIfNeeded()
}
}

Related

Do I need to add constraints to my UIToolBar if I'm adding it as a subview to my UIPickerView?

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.

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)
}
}

Can't make UIToolBar black color with white button item tint (ios 9, Swift)

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()

How to show and add toolbar buttons to UITableViewController with Swift

I am trying to programatically show and add toolbar buttons to a toolbar in a UITableViewController embedded in a UINavigationController. The toolbar appears but no buttons appear. Here is my code:
var items = [UIBarButtonItem]()
items.append(UIBarButtonItem.init(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil))
items.append(UIBarButtonItem(title: "Clear", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("btnClearAction")))
self.navigationController!.setToolbarHidden(false, animated: true)
self.navigationController!.setToolbarItems(items, animated: false)
While migrating my app to swift, I just found out I had the same issue. Only I'm trying to add it to a left menu controller which holds a table view. Shouldn't be all that different?
I just now got it solved by creating the toolbar programmatically.
Here's what I did:
Under the class
class LeftViewController: ViewController, UITableViewDataSource, UITableViewDelegate {
var tableView: UITableView!
var toolBar: UIToolbar!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 45/255, green: 45/255, blue: 45/255, alpha: 1.0)
self.tableView = UITableView(frame: self.view.bounds, style: .Plain)
self.tableView.delegate = self
self.tableView.dataSource = self
self.view.addSubview(self.tableView)
//UPDATE #3
self.tableView.frame = CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height-20)
self.edgesForExtendedLayout = .None
navigationController?.navigationBar.barTintColor = UIColor.blackColor()
navigationController?.navigationBarHidden = true
let Button1 = UIBarButtonItem(title: "Button1", style: .Plain, target: self, action: "your action")
let Button2 = UIBarButtonItem(title: "Button2", style: .Plain, target: self, action: "your action")
let Button3 = UIBarButtonItem(title: "Button3", style: .Plain, target: self, action: "your action")
let Button4 = UIBarButtonItem(title: "Button4", style: .Plain, target: self, action: "your action")
//Flexiable Space
let flexiableItem = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil)
//UPDATE #2
toolbarItems = [Button1, Button2, flexiableItem, Button3, Button4]
}
Obviously style your buttons, view, cells etc..however you want.
I did leave a lot out of what I posted because it didn't pertain to the topic.
Hope this helps.
UPDATE:
Awesome. One fix brings on another problem.
My toolbar vanishes when rotating the device. Rotate back and the buttons are gone. Could just be something in my project but yah.
UPDATE #2:
Answer updated with working code. Removed the toolBar I made and found a solution which works. Even with rotation.
UPDATE #3:
Sets the table view 20px creating a "status bar" and reduces the bottom of the table view by 20px so it fits on top of the toolbar.

Change UIBarButtonItem's button title in inputAccessoryView of UITextView after created?

I've created a inputAccessoryView for UITextView in viewDidLoad:
var keyBoardToolBar: UIToolbar = UIToolbar(frame: CGRectMake(0, 0, self.view.frame.size.width, 50))
keyBoardToolBar.barStyle = UIBarStyle.Default
var firstButton: UIBarButtonItem = UIBarButtonItem(title: "firstButton", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("firstButtonAction"))
var flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
var done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: Selector("doneButtonAction"))
var items = NSMutableArray()
items.addObject(firstButton)
items.addObject(flexSpace)
items.addObject(done)
keyBoardToolBar.items = items as [AnyObject]
keyBoardToolBar.sizeToFit()
self.tv.inputAccessoryView = keyBoardToolBar
And I want to change the firstButton's button text in other function (after viewDidLoad). So how can I do? Thanks!
I var the firstButton: UIBarButtonItem just inside the class before viewDidLoad and change it's title use firstButton.title. :)