How to show and add toolbar buttons to UITableViewController with Swift - 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.

Related

UIBarButtonItem programmatically change color

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

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.

How to make a toolbar be attached to bottom iOS Swift

I have a ploblem with tab bar and navigation bar. There's a toolbar I need to display on top of the tabbar, but attached to the very bottom.
For now I'm getting this:
My code is:
private func showToolBar() {
tabBarController?.tabBar.isHidden = true
navigationController?.setToolbarHidden(false, animated: true)
let archiveButton = UIBarButtonItem(image: #imageLiteral(resourceName: "deactivateIcons"), style: .plain, target: self, action: #selector(archive))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
let refreshButton = UIBarButtonItem(image: #imageLiteral(resourceName: "changeStatusIcons"), style: .plain, target: self, action: #selector(refresh))
archiveButton.tintColor = Colors.Purple
refreshButton.tintColor = Colors.Purple
setToolbarItems([archiveButton, flexibleSpace, refreshButton], animated: true)
navigationController?.toolbar.setShadowImage(UIImage(), forToolbarPosition: .bottom)
}
So the toolbar appears exactly on top of the tabbar. How to solve this? Thanks in advance!
Try this:
put that code in the last line of your showToolBar() function
let screenSize: CGRect = UIScreen.main.bounds
navigationController?.toolbar.frame = CGRect(x: 0, y: screenSize.height - tabBarHeight - 50, width: screenSize.width, height: 50)

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

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. :)