The UIButton on UIToolBar seems to be not working - ios

Here's my code
override func viewDidLoad() {
super.viewDidLoad()
let button1 = UIButton(frame: CGRect(x: 50, y: 50, width: 30, height: 30))
button1.setTitle("hi", for: .normal)
button1.setTitleColor(.blue, for: .normal)
button1.setTitleColor(.black, for: .highlighted)
button1.addTarget(self, action: #selector(self.barItem2Clicked(sender:)), for: .touchUpInside)
button1.backgroundColor=UIColor.red
let barButton1 = UIBarButtonItem(customView: button1)
toolBar1.items?.append(barButton1)
}
method barItem2Clicked :
func barItem2Clicked(sender :Any?) {
NSLog("hello")
}
I wanted to use UIButton add to UIToolBar, but the action of button1 can not be called, and the Highlighted effect is not shown too.
I clicked the button1 I just added, but the method barItem2Clicked never called.
Did I missed something?
Thanks

Please make sure that the toolBar1 is connected
I just tried with your code and it seems to be working.

Related

How to assign a button’s action in code using #objc mark for given function?

Hi for this question I found answer on How to create a button programmatically? however still facing the errors: "Argument of '#selector' cannot refer to local function 'plusOne(sender:)'" and "#objc can only be used with members of classes, #objc protocols, and concrete extensions of classes". If you can advice.
let button = UIButton()
button.frame = CGRect(x: 150, y: 300, width: 60, height: 60)
button.setTitle("Click", for: .normal)
button.setTitleColor(UIColor.blue, for: .normal)
button.addTarget(self, action: #selector(plusOne), for: .touchUpInside)
self.view.addSubview(button)
#objc func plusOne(sender: UIButton!) {
self.count += 1
self.label.text = "\(self.count)"
}
The problem you have is that you've nested the #objc func plusOne(sender: UIButton!) within viewDidLoad (which was why i asked the initial question about scope). You need to move it out to a class-scope method.
override func viewDidLoad() {
// all the usual stuff...
let button = UIButton()
button.frame = CGRect(x: 150, y: 300, width: 60, height: 60)
button.setTitle("Click", for: .normal)
button.setTitleColor(UIColor.blue, for: .normal)
button.addTarget(self, action: #selector(plusOne), for: .touchUpInside)
self.view.addSubview(button)
}
#objc func plusOne(sender: UIButton!) {
self.count += 1
self.label.text = "\(self.count)"
}
The name of the method is plusOne(sender:), the argument labels make part of the name

Fixing "use of unresolved identifier 'addTarget'" while adding func to button click event

I've created a UIButton programmatically as shown below:
let buttons: [UIButton] = [UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 50))];
Now if I try to add a function to it programmatically like this:
[buttons[0] addTarget:self action:#selector(buttonClicked:)forControlEvents:UIControlEventTouchUpInside]
I get an error saying that addTarget is not defined.
How do I fix this?
you are try to use the Objective-C syntax in swift, this is entirely wrong, use your code as like
buttons.first?.addTarget(self, action: #selector(self.buttonClicked(_:)), for: .touchUpInside)
and handle the action as like
#objc func buttonClicked( _ sender: UIButton) {
print("buttonClicked Action Found")
}
Ref : Apple Document for UIButton
First of all you are creating [UIButton] which is Array of UIButton and it's not a single Button.
You can not create Array of UIButton that way. You will need a for loop for that and you need to update the frame accordingly.
And you can create a single UIButton this way:
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
then you can add it into the UIView this way:
self.view.addSubview(button)
Without above line it your button will not show into your screen.
Next if you want to add action to that button you can do it by adding this line in your button code:
button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
and it will need a helper method which will execute when button will click.
#objc func buttonClicked(_ sender: UIButton) {
//Perform your action when button is clicked.
}
And you also need to apply backgroundColor and setTitle to the button.
and your final code will look like:
let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
button.backgroundColor = UIColor.green
button.setTitle("Test Button", for: .normal)
button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
self.view.addSubview(button)

Change Color of Programmatically Created Button when Pressed

I'm using a function to create multiple buttons for my game.
func createButton() {
let button = UIButton()
button.setTitle("", for: .normal)
button.frame = CGRect(x:15, y: 50, width: 200, height:100)
button.backgroundColor = UIColor.red
self.view.addSubview(button)
button.addTarget(self, action: Selector(("buttonPressed:")), for:
.touchUpInside)
}
I call this function once for testing in viewDidLoad function, but I don't know what code I should put into my buttonPressed() function for the color of my button to change? I tried doing
self.backgroundColor = UIColor.blue
but that didn't work. I also tried using UIButton and button instead of self, but both of those didn't work either. What should I do?
Your code isn't clean Swift 4 code. Here's how to do this:
Create your button like you are, but change Selector to #selector:
func createButton() {
let button = UIButton()
button.setTitle("", for: .normal)
button.frame = CGRect(x:15, y: 50, width: 200, height:100)
button.backgroundColor = UIColor.red
self.view.addSubview(button)
button.addTarget(self, action: #selector((buttonPressed)), for: .touchUpInside)
}
Use the sender that is automatically added:
#objc func buttonPressed(sender: UIButton) {
sender.backgroundColor = UIColor.blue
}
Additionally may I offer a few suggestions?
Check the background color before changing it. No sense in needlessly changing a button that is already blue.
Since you aren't setting the title to your button, set the tag property (you can even add this as a parameter to createButton). This way you can know which button was tapped.
Just make the button an instance property.
let changingButton = UIButton()
func createButton() {
changingButton.backgroundColor = UIColor.red
changingButton.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
}
#objc func buttonPressed() {
changingButton.backgroundColor = UIColor.blue
}

Stuck with adding target to button programmatically

I've created a UIButton and I want it to print some message when it's pressed.
So I did something like this:
In loadView()
button.addTarget(self, action: #selector(ViewController.pressButton(button:)), for: .touchUpInside)
A method:
func pressButton(button: UIButton) {
NSLog("pressed!")
}
But nothing happens when I click the button.
Add the button code in your viewDidLoad and it will work for you:
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
button.backgroundColor = UIColor.gray
button.addTarget(self, action: #selector(pressButton(button:)), for: .touchUpInside)
self.view.addSubview(button)
}
func pressButton(button: UIButton) {
NSLog("pressed!")
}
You don´t need to add ViewController.pressButton to selector, it´s enough with the function name.
Swift 4.x version:
let button = UIButton(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
button.backgroundColor = .gray
button.tag = 0
button.addTarget(self, action: #selector(pressButton(_:)), for: .touchUpInside)
self.view.addSubview(button)
#objc func pressButton(_ button: UIButton) {
print("Button with tag: \(button.tag) clicked!")
}
Swift 5.1 version:
let button = UIButton(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
button.backgroundColor = .gray
button.tag = 100
button.addTarget(self, action: #selector(pressButton), for: .touchUpInside)
self.view.addSubview(button)
#objc func pressButton(button: UIButton) {
print("Button with tag: \(button.tag) clicked!")
}
try this in Swift3!
button.addTarget(self, action: #selector(self.pressButton(button:)), for: .touchUpInside)
#objc func pressButton(button: UIButton) { NSLog("pressed!") }
Use the following code.
button.addTarget(self, action: #selector(FirstViewController.cartButtonHandler), for: .touchUpInside)
Your class name corresponds to FirstViewController
And your selector corresponds to the following function
func cartButtonHandler() {
}
In swift 3 use this -
object?.addTarget(objectWhichHasMethod, action: #selector(classWhichHasMethod.yourMethod), for: someUIControlEvents)
For example(from my code) -
self.datePicker?.addTarget(self, action:#selector(InfoTableViewCell.datePickerValueChanged), for: .valueChanged)
Just give a : after method name if you want the sender as parameter.
You mention that the addTarget call is in loadView(). Is this in your custom subview, of some kind, or the viewController?
From your selector, it's targeting a method in your ViewController class, but if the target for this action is the view itself, then it would make sense that the action is not going through.
If you declare your button in a viewController, and in viewDidLoad add this target as above, then the message should be printed as you're looking for. I believe you are "targetting" the wrong class with your action.
let cancelButton = UIButton.init(frame: CGRect(x: popUpView.frame.size.width/2, y: popUpView.frame.size.height-20, width: 30, height: 30))
cancelButton.backgroundColor = UIColor.init(patternImage: UIImage(named: cancelImage)!)
cancelButton.addTarget(self, action: #selector(CommentsViewController.canceled), for:.touchUpInside)
Add the button code in override func viewDidLoad() method
Make sure your action handler tagged with #IBAction like this:
#IBAction func pressButton(button: UIButton) {
print("pressed!")
}
Then it will work!

Why isn't my UIButton in a UIBarButtonItem not showing in the Nav Bar?

I have a UINavigationController which changes the UIBarButtonItem in the top right corner, depending on the state of the app.
When view did load I initialize the buttons I need
var editBarButton: UIBarButtonItem!
var logoutBarButton: UIBarButtonItem!
var showRepositoryBarButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
editButton = UIButton()
editButton.setImage(UIImage(named: "icon pencil"), forState: .Normal)
editButton.frame = CGRectMake(0, 0, 30, 30)
editButton.addTarget(self, action: #selector(UserProfileNavigatorController.onEditClick), forControlEvents: .TouchUpInside)
editBarButton = UIBarButtonItem(customView: editButton)
let logoutButton = UIButton()
logoutButton.setImage(UIImage(named: "icon logout"), forState: .Normal)
logoutButton.frame = CGRectMake(0, 0, 30, 30)
logoutButton.addTarget(self, action: #selector(UserProfileNavigatorController.onLogoutClick), forControlEvents: .TouchUpInside)
logoutBarButton = UIBarButtonItem(customView: logoutButton)
let showRepositoryButton = UIButton()
logoutButton.setImage(UIImage(named: "icon logout"), forState: .Normal)
logoutButton.frame = CGRectMake(0, 0, 30, 30)
logoutButton.addTarget(self, action: #selector(UserProfileNavigatorController.onShowRepositoryOnWebClick), forControlEvents: .TouchUpInside)
showRepositoryBarButton = UIBarButtonItem(customView: showRepositoryButton)
presenter.viewDidLoad()
}
And depending on the situation, I change the buttons displayed in this way
func showUserProfile() {
navigationItem.setRightBarButtonItems([editBarButton, logoutBarButton], animated: false)
Router.showUserProfileInNavigatorController(self)
}
func showRepository(repository: Repository) {
navigationItem.setRightBarButtonItems([showRepositoryBarButton], animated: false)
Router.showRepository(self, repository: repository)
}
Even though this code is actually executed, nothing appears in the top right corner.
The problem was that that code was running in the UINavigationController. Instead, it's the UIViewController who must show the buttons in the UINavigationController.
So just moving the code inside the UIViewController is working.
Note that there are multiple problems with your code. First, note that while UIButton() will return a non-optional, UIImage may return an optional. So you really have no idea now whether you actually have typed the names of your images correctly. I created a simple project using your code above, with no images in it, and duplicated that if the images are nil, that nothing shows.
Then adding images, I only got two images showing. Looking closely at your code, the 3rd image re-defines loginButton but does not set any properties on showRepositoryButton.
Several suggestions:
us "do { ... }" to create a sub context to avoid unintended variable re-use
if using a UIButton, use the designated initializer (UIButton(type:...)
better still, use a UIBarButtonItem(image: ...)
pay really close attention to optionals, and let forced unwrapping crash at the appropriate time (or use an assert, guard, or precondition)
Without drastically modifying your code, here is what works fine for me:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Howdie!"
do {
let button = UIButton()
let image = UIImage(named: "02-redo")!
button.setImage(image, forState: .Normal)
button.frame = CGRectMake(0, 0, 30, 30)
button.addTarget(self, action: #selector(onEditClick), forControlEvents: .TouchUpInside)
editBarButton = UIBarButtonItem(customView: button)
}
do {
let button = UIButton()
let image = UIImage(named: "03-loopback")!
button.setImage(image, forState: .Normal)
button.frame = CGRectMake(0, 0, 30, 30)
button.addTarget(self, action: #selector(onLogoutClick), forControlEvents: .TouchUpInside)
logoutBarButton = UIBarButtonItem(customView: button)
}
do {
let button = UIButton()
let image = UIImage(named: "04-squiggle")!
button.setImage(image, forState: .Normal)
button.frame = CGRectMake(0, 0, 30, 30)
button.addTarget(self, action: #selector(onShowRepositoryOnWebClick), forControlEvents: .TouchUpInside)
showRepositoryBarButton = UIBarButtonItem(customView: button)
}
navigationItem.setRightBarButtonItems([editBarButton, logoutBarButton, showRepositoryBarButton], animated: false)
}

Resources