I have a custom UIToolbar created in Storyboard containing rewind, pause, and fast-forward UIBarButtonItems. I am attempting to replace the pause button with a play button when clicked. My code is as follows:
#IBOutlet weak var bottomToolbar: UIToolbar!
#IBAction func playPause() {
var newButton: UIBarButtonItem
if !self.timer.valid {
let aSelector : Selector = "updateTime"
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: aSelector, userInfo: nil, repeats: true)
newButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "playPause")
}
else {
self.timer.invalidate()
newButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "playPause")
}
var items = self.bottomToolbar.items
items?[3] = newButton
self.bottomToolbar.setItems(items, animated: true)
}
The toolbar is initialized with a dark gray background with white buttons. However, after the attempted button switch, the entire toolbar goes white. Any ideas?
UPDATE 1:
So after messing around with the colors and stepping through the code a bit more, I've found that only the pause/play button disappears in addition to the toolbar going white. But even after disappearing, clicking where it should be still sends a signal to the VC. And trying to reset the toolbar background to dark gray doesn't help.
I had a similar problem recently. What helped was setting toolbar.Items to an empty array before setting it again to your items.
My swift is very limited, so please excuse any compiler errors:
items = self.bottomToolbar.items
self.bottomToolbar.setItems:([], animated: false)
items?[3] = newButton
self.bottomToolbar.setItems(items, animated: true)
Related
I have five pickers in total. I want to create a done button for each one of them. I want to use a different selector for each one to to do different actions. To set up the done buttons I was trying to use the same method for all of them, but I do not know how to pass a function argument into the selector in Swift.
func createDoneButton(txtField: UITextField, donePressed: /* What do I need here? */) {
let toolbar = UIToolbar() // create toolbar
toolbar.sizeToFit() // toolbar fits the size of the screen
let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed)) // action when the done button was pressed
toolbar.setItems([doneBtn], animated: true)
txtField.inputAccessoryView = toolbar
}
You can find the answer in your question :)
Simply use Selector parameter type, and no need #selector()
func createDoneButton(txtField: UITextField, donePressed: Selector){
let toolbar = UIToolbar() // create toolbar
toolbar.sizeToFit() // toolbar fits the size of the screen
let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: donePressed) // action when the done button was pressed
toolbar.setItems([doneBtn], animated: true)
txtField.inputAccessoryView = toolbar
}
I have two buttons inside of a toolbar that is positioned at the bottom of the screen. I would like to center those buttons within the toolbar. Everything I have found is focused on centering buttons within a nav bar and I am unsure of how to approach this issue. What am I missing?
This is the UI I am attempting to emulate:
Adding a flexible space to the left and right of the buttons centered the buttons inside of the toolbar. Thanks to Midhun MP for the tip.
Thks #Andrew, it works
but for someone who wants it from code here is the example in Swift 5.0
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setToolbarHidden(false, animated: true)
let spaceItemLeft = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
let nextItem = UIBarButtonItem(title: "NEXT", style: .plain, target: self, action: #selector(nextTapped))
let spaceItemRight = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
toolbarItems = [spaceItemLeft, nextItem, spaceItemRight]
}
#objc func nextTapped() {
print("NEXT Tapped")
}
I have added a navigation bar to the top of a view controller. I am trying to control whether a button is visible based a condition, but I am having trouble adding the button. So far I have,
var addButton: UIBarButtonItem = UIBarButtonItem(title: "test", style: .done, target: self, action: #selector(addTapped))
override func viewDidLoad() {
super.viewDidLoad()
let boool = true
if boool {
self.navigationItem.rightBarButtonItem = self.addButton
}
else {
self.navigationItem.rightBarButtonItem = nil
}
}
func addTapped(sender: AnyObject) {
print("hjxdbsdhjbv")
}
I believe it is not working properly because I have added a navigation bar into the VC, instead of using a navigation controller and working with the bar there. I was wondering if there was a way to work with this navigation bar.
It’s simple. Put this line of code to the viewDidLoad:
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "test", style: .done, target: self, action: #selector(addTapped))
Updated for Swift 4 or later:
A custom function:
#objc func action(sender: UIBarButtonItem) {
// Function body goes here
}
(Custom) Right bar button item:
self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: "some_text", style: .done, target: self, action: #selector(self.action(sender:)))
(Custom) Left bar button item:
self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(title: "some_text", style: .done, target: self, action: #selector(self.action(sender:)))
Also you can add a system bar button items something like this: UIBarButtonItem.SystemItem Defines system-supplied images for bar button items: .add, .done, .cancel, .edit, .save, .compose, .reply, .organize and more.
(System) Right bar button item:
self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonItem.SystemItem.add, target: self, action: #selector(self.action(sender:)))
(System) Left bar button item:
self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonItem.SystemItem.add, target: self, action: #selector(self.action(sender:)))
let rightBarButtonItem = UIBarButtonItem.init(image: UIImage(named: "EditImage"), style: .done, target: self, action: #selector(ViewController.call_Method))
self.navigationItem.rightBarButtonItem = rightBarButtonItem
You say you added a UINavigationBar to your view controller via storyboard, but looking at the code you provided there is no outlet connection to your navigation bar in IB.
In order to access self.navigationItem your view controller must be embedded in a UINavigationController or be part of a hierarchy which is. Unless you have a need for a custom navigation bar on an individual view controller, I suggest removing that from Interface Builder, then making sure either the view controller in question is embedded in a UINavigationController or it is being pushed onto the navigation stack from another controller which is embedded in a navigation controller and then you should see your UIBarButtonItem.
Firstly, you need to connect you navigation bar to an IBOutlet so that you can refer to it in your code. After that, this code should work:
let navigationItem = UINavigationItem(title: "Title")
navigationItem.rightBarButtonItem = self.addButton
navigationItem.hidesBackButton = true
self.navigationBar.pushItem(navigationItem, animated: false)
Swift 4.2;
Add viewController
override func viewDidLoad() {
super.viewDidLoad()
self.addNavigationBarButton(imageName: "ic_back", direction:.left)
}
Add Class your API or Utility Class
public func addNavigationBarButton(imageName:String,direction:direction){
var image = UIImage(named: imageName)
image = image?.withRenderingMode(.alwaysOriginal)
switch direction {
case .left:
self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
case .right:
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
}
}
#objc public func goBack() {
self.navigationController?.popViewController(animated: true)
}
public enum direction {
case right
case left
}
tested in Xcode 10.2, swift 5.0;
First, I have have embedded my ViewController in UINavigationController in IB.
Then in ViewDidLoad include these lines
self.title = "orange"
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(changeLayout)).
Note - accessing title, or adding button through navigation controller did not work. For example : setting title - Self.navigationcontroller.navigationItem.title did not work ,
I am currently working on making the register section of an iOS app in Swift 3.0.2.
Here's a gif
of the problem I am having. Watch the toolbar above the keyboard as the segue occurs. It flashes to a darker shade before it fully loads. This occurs whether or not the keyboard is active throughout the process (ViewController has toolbar as inputAccessoryView).
Here is the toolbar implementation (it's the same for each View).
fileprivate let toolbar = { () -> UIToolbar in
let toolbar = UIToolbar()
toolbar.barStyle = .default
toolbar.isTranslucent = true
toolbar.tintColor = UIColor(netHex: Constant.Color.darkerCrimsonColor)
toolbar.isUserInteractionEnabled = true
toolbar.sizeToFit()
return toolbar
}()
override var inputAccessoryView: UIView? {
return toolbar
}
fileprivate func setupToolbar() {
let otherButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(title: "Next", style: UIBarButtonItemStyle.done, target: self, action: #selector(nextViewController))
toolBar.setItems([otherButton, otherButton, doneButton], animated: true)
nameTextField.inputAccessoryView = toolbar
}
The entire app is made programmatically. I remade the essentials of the project again through Storyboard and ran into the same problem.
My question is: is this intended behavior? If not, what can I do about this? Is there a way to suppress this behavior completely?
Thanks in advance for your time and consideration!
I know this question has been asked before and I've found two different lines of code that purport to perform a change in the identifier for a bar button item in a navigation bar. Both compile, but neither has any effect on the identifier. I start the program with the identifier set to a Play button, and want to change it to a Pause button. I've run these two lines of code both in viewDidLoad() and inside
IBAction func startButton(sender: AnyObject) {
Here is the code. Can anyone tell me why the button identifier is not changing? And, is the rightButton/leftButton as obvious as it appears, or is there something about words in the code I don't get.
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Pause, target: self, action: "startButton:")
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "startButton"), animated: true)
Here is the entire viewDidLoad, where it does not work either.
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Pause, target: self, action: "startButton:")
}
Try below code to toggle button in UINavigationBar
In override func viewDidLoad() writes
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem:UIBarButtonSystemItem.Play, target: self, action:Selector("startButton:"))
and create two #IBAction for button
#IBAction func startButton(sender: UIButton!) {
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "stopButton:"), animated: true)
}
#IBAction func stopButton(sender: UIButton!) {
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "startButton:"), animated: true)
}
#Bendrix, you can see code which I have tried my view controller code
And video after run this code in simulator app in simulator