I used the following tutorial to programmatically create a UIBarButtonItem in Swift, but the icon isn't properly aligned to the border. Here's the code for the button. Can anyone tell me how to modify the code below to properly align the UIBarButtonItem Image?
The 1st image shows the location of the programmatically created uibarbuttonitem, and the 2nd image shows the uibarbuttonitem created from storyboard. I want the programmatically created uibarbuttonitem to look like uibarbuttonitem created using storyboard. Thanks for the help!
var button: UIButton = UIButton()
button.setImage(UIImage(named: "leftArrow.png"), forState: .Normal)
button.frame = CGRectMake(0, 0, 40, 40)
button.targetForAction("actioncall:", withSender: nil)
var leftBarButtonItem:UIBarButtonItem = UIBarButtonItem()
leftBarButtonItem.customView = button
self.navigationItem.leftBarButtonItem = leftBarButtonItem
Also, how do I properly set the action for when the uibarbuttontiem is pressed? I tried the following but it's never called.
func actioncall(sender: AnyObject){
println("action")
}
Edit 1: I updated the code as follows thanks to agy's response.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
if (cond){
var button: UIButton = UIButton()
button.setImage(UIImage(named: "leftArrow.png"), forState: .Normal)
button.frame = CGRectMake(0, 0, 40, 40)
button.addTarget(self, action: "actioncall:", forControlEvents: .TouchUpInside)
var leftBarButtonItem:UIBarButtonItem = UIBarButtonItem()
leftBarButtonItem.customView = button
var negativeSpacer:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
negativeSpacer.width = -20; // set the value you need
self.navigationItem.leftBarButtonItems = [negativeSpacer,leftBarButtonItem]
}
}
func actioncall(sender: UIButton!){
println("action")
}
but the action still fails. The app crashes when I press the uibarbuttontiem and I get the following error message
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppName.ProfileViewController actioncall:]: unrecognized selector sent to instance 0x7a07a470'
What's the correct function for the action?
Edit 2: The actioncall is in the same class as where I'm creating the UIBarButtonItem. I'm setting the leftbarbutton on viewwillappear because depending on who views this viewcontroller, the option to go back will replace the previous option located on the leftbarbutton.
Try adding a negative spacer, and change the method targetForAction for addTarget:
var button: UIButton = UIButton()
button.setImage(UIImage(named: "leftArrow.png"), forState: .Normal)
button.frame = CGRectMake(0, 0, 40, 40)
button.addTarget(self, action: "actioncall:", forControlEvents: .TouchUpInside)
var leftBarButtonItem:UIBarButtonItem = UIBarButtonItem()
leftBarButtonItem.customView = button
var negativeSpacer:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
negativeSpacer.width = -5; // set the value you need
self.navigationItem.leftBarButtonItems = [negativeSpacer,leftBarButtonItem]
func actioncall(sender: UIButton!){
print("Called")
}
Related
In the following code I have a couple buttons showing as an inputAccessoryView when inputFieldOne is in editing mode, when you tap First Button, it inputs ONE inside inputFieldOne and when I tap Second Button it inputs TWO inside inputFieldOne. It works as expected but what I would like to be able to do is re-use these buttons in multiple UITextFields. In other words, if I have another UTTextField called inputFieldTwo, I would like to be able to also input the values from those buttons when they're tapped.
How can I keep track of what UITextField is currently in editing mode so I can append the values from the buttons?
#IBOutlet weak var inputFieldOne: UITextField!
#IBOutlet weak var inputFieldTwo: UITextField!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
addButtonsToKeyboard()
}
func addButtonsToKeyboard(){
// First button
let button1 = UIButton()
button1.setTitle("First Button", for: UIControl.State())
button1.addTarget(self, action: #selector(buttonKeyPress), for: UIControl.Event.touchUpInside)
let barButton1 = UIBarButtonItem()
barButton1.customView = button1
// Second button
let button2 = UIButton()
button2.setTitle("Second Button", for: UIControl.State())
button2.addTarget(self, action: #selector(buttonKeyPress), for: UIControl.Event.touchUpInside)
let barButton2 = UIBarButtonItem()
barButton2.customView = button2
/// UIToolbar.
let toolBar = UIToolbar()
toolBar.tintColor = UIColor.blue
toolBar.barTintColor = UIColor.red
toolBar.items = [barButton1, barButton2]
toolBar.sizeToFit()
inputFieldOne.inputAccessoryView = toolBar
}
#objc func buttonKeyPress(_ sender: UIButton){
switch sender.currentTitle!{
case "First Button":
inputFieldOne.text = "ONE"
case "Second Button":
inputFieldOne.text = "TWO"
default: break
}
}
There are many ways to make it reusable as i have very limited time so i suggest you can do it with Extension
You can use it for you all textfield
So here is the code snippet:
extension UITextField
{
// you can pass here array of UIbarbutton also
func addButtonsToKeyboard(){
// First button
let button1 = UIButton()
button1.setTitle("First Button", for: UIControl.State())
button1.addTarget(self, action: #selector(buttonKeyPress), for: UIControl.Event.touchUpInside)
let barButton1 = UIBarButtonItem()
barButton1.customView = button1
// Second button
let button2 = UIButton()
button2.setTitle("Second Button", for: UIControl.State())
button2.addTarget(self, action: #selector(buttonKeyPress), for: UIControl.Event.touchUpInside)
let barButton2 = UIBarButtonItem()
barButton2.customView = button2
/// UIToolbar.
let toolBar = UIToolbar()
toolBar.tintColor = UIColor.blue
toolBar.barTintColor = UIColor.red
toolBar.items = [barButton1, barButton2]
toolBar.sizeToFit()
self.inputAccessoryView = toolBar
}
#objc func buttonKeyPress(_ sender: UIButton){
switch sender.currentTitle!{
case "First Button":
self.text = "ONE"
case "Second Button":
self.text = "TWO"
default: break
}
}
}
And with you textfield object you can add it with below code
txtSwift.addButtonsToKeyboard()
Hope it help you!!!
How to add button above the keyboard like this one in Stack Exchange app? And when you long press the text in UITextView How to add "Select" and "Select All"?
The first question, you can set textField's inputAccessoryView to your custom view, this can customize the keyboard's header.
The result:
You can do it like below;
first, you should instance the view you want to add above the keyboard.
class ViewController : UIViewController {
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
textField.inputAccessoryView = Bundle.main.loadNibNamed("CustomAccessoryView", owner: self, options: nil)?.first as! UIView?
In your CustomAccessoryView, you can set the action of the button:
import UIKit
class CustomAccessoryView: UIView {
#IBAction func clickLoveButton(_ sender: UIButton) {
print("Love button clicked")
}
}
I would recommend to create a toolbar for your UITextField's accessoryView property.
The idea is to add this toolbar once, before the textfield would show for the first time. Therefore, we assign the delegate to self, and override the textFieldShouldBeginEditing delegate call with our implementation to add the accessoryView.
Here is a simple example, how can u achieve it:
import UIKit
class ViewController: UIViewController {
// your `UITextfield` instance
// Don't forget to attach it from the IB or create it programmaticly
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Assign the delegate to self
textField.delegate = self
}
}
// MARK: Create extension to conform to UITextfieldDelegate
extension ViewController: UITextFieldDelegate {
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
setupTextFieldsAccessoryView()
return true
}
func setupTextFieldsAccessoryView() {
guard textField.inputAccessoryView == nil else {
print("textfields accessory view already set up")
return
}
// Create toolBar
let toolBar: UIToolbar = UIToolbar(frame:CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 44))
toolBar.barStyle = UIBarStyle.black
toolBar.isTranslucent = false
// Add buttons as `UIBarButtonItem` to toolbar
// First add some space to the left hand side, so your button is not on the edge of the screen
let flexsibleSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil) // flexible space to add left end side
// Create your first visible button
let doneButton: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(didPressDoneButton))
// Note, that we declared the `didPressDoneButton` to be called, when Done button has been pressed
toolBar.items = [flexsibleSpace, doneButton]
// Assing toolbar as inputAccessoryView
textField.inputAccessoryView = toolBar
}
func didPressDoneButton(button: UIButton) {
// Button has been pressed
// Process the containment of the textfield or whatever
// Hide keyboard
textField.resignFirstResponder()
}
}
This should be your output:
You'll have to use the inputAccessoryView of your textfield.
you can put the code snippet below in your viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 60))
button.backgroundColor = UIColor.blue
button.setTitle("NEXT", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.addTarget(self, action: #selector(self. yourButton), for: .touchUpInside)
numtextField.inputAccessoryView = button
}
#objc func nextButton()
{
print("do something")
}
Just copy and paste simple code for you accessory button embedded with keypad
func addKeyboardToolbar() {
let ViewForDoneButtonOnKeyboard = UIToolbar()
ViewForDoneButtonOnKeyboard.sizeToFit()
let button = UIButton.init(type: .custom)
button.setImage(UIImage.init(named: "login-logo"), for: UIControlState.normal)
button.addTarget(self, action:#selector(doneBtnfromKeyboardClicked), for:.touchUpInside)
button.frame = CGRect.init(x: 0, y: 0, width:UIScreen.main.bounds.width, height: 30) //CGRectMake(0, 0, 30, 30)
let barButton = UIBarButtonItem.init(customView: button)
ViewForDoneButtonOnKeyboard.items = [barButton]
postTextView.inputAccessoryView = ViewForDoneButtonOnKeyboard
}
func doneBtnfromKeyboardClicked (){
self.contentView.endEditing(true)
}
to add a toolbar with a done button which dismisses the keyboard above a UITextField you can write a UITextField extension with the following function:
public func addAccessoryView() {
let doneButton = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action: "resignFirstResponder")
let flexSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
let toolbar = UIToolbar()
toolbar.barStyle = UIBarStyle.Default
toolbar.translucent = true
toolbar.tintColor = Color.blue
toolbar.sizeToFit()
toolbar.setItems([flexSpace, doneButton], animated: false)
toolbar.userInteractionEnabled = true
self.inputAccessoryView = toolbar
}
you can then call the function in your textfield like this:
textfield.addAccessoryView()
let button = UIButton()
button.setImage(UIImage(named: "coin_icon"), forState: UIControlState.Normal)
button.addTarget(self, action:#selector(Profile.goCoin), forControlEvents: UIControlEvents.TouchDragInside)
button.frame=CGRectMake(0, 0, 30, 30)
let barButton = UIBarButtonItem(customView: button)
self.navigationItem.rightBarButtonItem = barButton
My code is this to add a bar button on navigation bar.
However, i need to change the title of button in a function
func changetitle() {
self.navigationItem.rightBarButtonItem?.title = "Change"
}
I tried this one but didn't work.
How can i change the title of this button?
You need to access the UIButton from the UIBarButtonItem and change the title of the UIButton.
func changetitle() {
let item = self.navigationItem.rightBarButtonItem!
let button = item.customView as! UIButton
button.setTitle("Change", for: .normal)
}
UIbutton remove from MenuScene before I jump into GameScene, or when I don't remove, the button is visible in GameScene, but I draw in MenuScene, why is that? What is the best way to create buttons and change the images of button?
The code is:
var button: UIButton!
button = UIButton()
var buttonFrame = self.view!.frame
button?.frame = CGRectMake(0, 0, 200, 100)
let buttonImage = UIImage(named: "PlayButton")
let buttonClick = UIImage(named: "PlayButton-click")
button!.setImage(buttonImage, forState: UIControlState.Normal)
button!.setImage(buttonClick, forState: UIControlState.Highlighted)
button!.addTarget(self, action: "PlayButtonClick:", forControlEvents: UIControlEvents.TouchUpInside)
self.view?.addSubview(button)
func PlayButtonClick(sender: UIButton) {
self.view?.presentScene(GameScene(size:self.size),transition: .crossFadeWithDuration(1.2))
button.removeFromSuperview()
}
Try that in PlayButtonClick Method:
sender.hidden = true
This should probably do the trick.
button.hidden = true, or sender.hidden = true,
This hide the uibutton , but button is hide very early, before i enter the GameScene state, and i see that..
I'm creating a button in swift 2 and when I select it, I get signal SIGABRT and the app crashes. Heres the code:
let button = UIButton()//(type: UIButtonType.System) as UIButton!
button.setTitle("button", forState: .Normal)
button.setTitleColor(UIColor.blueColor(), forState: .Normal)
button.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
button.frame = CGRectMake(100, 100, 100, 100)
self.view.addSubview(button)
func buttonPressed(sender: UIButton!) {
print("ButtonIsSelected")
}
It brings me to AppDelegate.swift and in the middle of the NSLog it says: unrecognized selector sent to instance...
Please help. Anton
func buttonPressed(sender: UIButton!) {
print("ButtonIsSelected")
}
This method must be in your class body not in function body . As I guess you have done.