I UIButton using + buttonWithType:
What I need to figure out is how to manually change the button state. There are times when I need it to be set to "disabled."
I read through the UIButton documentation but I cannot seem to find anything about manually setting a button state.
Any thoughts would be greatly appreciated.
Did you try button.enabled = NO;?
Swift 5.0
button.isEnabled = false
there are also the states:
button.highlighted = NO;
button.selected = NO;
Objective C:
button.selected = Yes;
button.highlighted = NO;
button.enabled = Yes;
Swift 4:
button.isSelected = true
button.isEnabled = true
Also you can use:(swift 4)
if (button.state == .selected) {
//do something
}
You can manually set state of UIButton.
UIButton *btnCheck=[UIButton buttonWithType:UIButtonTypeCustom];
if(btncheck isselected])
{
btncheck.selected=FALSE;
}
else
{
btncheck.selected=TRUE;
}
You can do operation on UIButton as per your requirement like perform some action when UIButton is selected and while not selected.
Hope this will help you....
for Swift 3 you can use
button.isSelected = true
For anyone arriving here looking to change the 'state' of the button (as opposed to 'enabled'). Stephen is correct "This attribute is read only—there is no corresponding setter method."
What you really want to set is the state of the buttons cell.
[[myNSButtonOutlet cell] setState: NSOnState]; //Options NSOnState, NSOffState, NSMixedState
To accommodate the needs of setting a different button look when it's selected, set isSelected = true.
Here is an example of setting the state, and changing the UIButton appearance based on that state, using a quiz game environment:
if sender.titleLabel?.text == correctAnswer {
sender.isSelected = true
// Set title color and image based on 'selected' state.
sender.setTitleColor(.systemBlue, for: .selected)
sender.setImage(Utilities.sharedInstance.returnAnswerButtonImage(for: .correctlyAnswered).withRenderingMode(.alwaysOriginal), for: .selected)
sender.backgroundColor = .white
sender.tintColor = .systemBlue
// moveToNextQuestion()
} else {
sender.isSelected = true
sender.setTitleColor(.systemBlue, for: .selected)
sender.setImage(Utilities.sharedInstance.returnAnswerButtonImage(for: .incorrectlyAnswered).withRenderingMode(.alwaysOriginal), for: .selected)
sender.backgroundColor = .red
sender.tintColor = .systemBlue
}
Related
I am trying to change text of button button action. The font of the button not taken custom font. It will take default font. Please help on this issue I am enable to resolve this issue.
Heare is my code
#objc func moreAction(_ sender :UIButton) {
if fromBtn == "more"
{
fromBtn = "less"
sender.backgroundColor = .clear
sender.setTitle("- Less", for: .normal)
sender.titleLabel?.font = UIFont(name:"Lato-Bold",size:14)
index = sender.tag
tblView.reloadData()
}
else{
fromBtn = "more"
sender.backgroundColor = .clear
sender.setTitle("+ More", for: .normal)
sender.titleLabel?.font = UIFont(name:"Lato-Bold",size:14)
index = sender.tag
tblView.reloadData()
}
}
Thanking you in advance
Are you sure you added the font to xcode (here's the guide) and it matches the name?
It is also possible to reduce the number of repeated lines :)
fromBtn = fromBtn == "more" ? "more" : "less"
sender.backgroundColor = .clear
sender.setTitle(fromBtn == "more" ? "more" : "- Less", for: .normal)
sender.titleLabel?.font = UIFont(name:"Lato-Bold",size:14)
index = sender.tag
tblView.reloadData()
I want to change the image of a UIButton for different states. To achieve this, I'm using:
btn.setImage(UIImage(named: "blabla"), for .normal)
and
btn.setImage(UIImage(named: blabla2), for .disabled)
This only makes some appear dimmed.
What did I do wrong? I just want to make my button appearance the same for different states, how?
(my button type - .system).
This helped me (swift 3.0)
btn.setImage(UIImage(named:"yourFriend")?.withRenderingMode(.alwaysOriginal), for: .normal)
btn.setImage(UIImage(named:"yourFriend")?.withRenderingMode(.alwaysOriginal), for: .disabled)
You just need to set one for the state. And if you don't set another image for different state. It would look the same in all state.
button.setImage(image, forState: .Normal)
How to change UIButton image in Swift
For display disabled button set image
let btn = UIButton(type: .Custom)
btn.setImage(UIImage(named: blabla2), for .disabled)
Then
btn.enabled = false // to display Disable image
btn.enabled = true // to display Normal image
private let button1: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named:"firstButtonNormalStateImage"), for: .normal)
button.setImagesetImage(UIImage(named:"firstButtonSelectedStateImage"), for: .selected)
return button
}()
private let button2: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named:"secondButtonNormalStateImage"), for: .normal)
button.setImage(UIImage(named:"secondButtonSelectedStateImage"), for: .selected)
return button
}()
// implement for example in viewDidLoad()
button1.addTarget(self, action: #selector(firstButtonDidTap), for: .touchUpInside)
button2.addTarget(self, action: #selector(secondButtonDidTap), for: .touchUpInside)
// trigger actions
#objc func firstButtonDidTap() {
button1.isSelected = true
button2.isSelected = false
}
#objc func secondButtonDidTap() {
button2.isSelected = true
button1.isSelected = false
}
For whoever is still having this issue (currently Xcode 10.0) with a Custom button, I found I was able to change the text and/or image if instead of:
myButton.setTitle("Hi", for: [.normal])
I used this:
myButton.setTitle("Hi", for: []) //remove specific states
I don't know why .normal was not working for me, even though the button was definitely enabled. But maybe this will save someone else a headache!
You can simply do this by StoryBoard as well.
Select the button, got to identity inspector and do the following:-
Firstly set the buttonType to custom instead of system.
Secondly choose state Config to lets say default and give the imageName in "image" attribute, similarly choose other state configs (Highlighted, disabled, selected etc.) and set images as required by you.
Then later in the code you just have to control and set the state of the button, and respective image will be shown to you.
I have a agree button below two checkbox. i want to enable the agree button and also change the colour of agree button after both checkbox is checked. i have used custom images for checkbox.
i am using this code
This is my UIButton class
let selectedImage = UIImage(named: "checkbox_checked")
let unselectedImage = UIImage(named: "checkbox_unchecked")
class Qbutton: UIButton {
//Bool Property
var isChecked:Bool = false{
didSet{
if isChecked {
self.setImage(selectedImage, forState: UIControlState.Normal)
}else{
self.setImage(unselectedImage, forState: UIControlState.Normal)
}
}
}
override init(frame: CGRect){
super.init(frame:frame)
self.layer.masksToBounds = true
self.setImage(unselectedImage, forState: UIControlState.Normal)
self.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
self.isChecked = false
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
func buttonClicked(sender: UIButton) {
if(sender == self){
if isChecked == true{
isChecked = false
print("true")
self.setImage(unselectedImage, forState: UIControlState.Normal)
}else{
isChecked = true
print("false")
self.setImage(selectedImage, forState: UIControlState.Selected)
}
NSUserDefaults.standardUserDefaults().setObject(isChecked, forKey: "isBtnChecked")
NSUserDefaults.standardUserDefaults().synchronize()
}
}
}
AND THIS IS MY VIEW CONTROLLER CLASS WHERE I AM USING QBUTTON CLASS
checkBoxOne = Qbutton(frame: CGRectMake(X,Y,WIDTH,HEIGHT))
isChecked = NSUserDefaults.standardUserDefaults().boolForKey("isBtnChecked")
checkBoxOne.isChecked = isChecked
self.view.addSubview(checkBoxOne)
checkBoxTwo = Qbutton(frame: CGRectMake(X,Y,WIDTH,HEIGHT))
checkBoxTwo.isChecked = isChecked
self.view.addSubview(checkBoxTwo)
NOW I WANT TO CHANGE THE COLOR OF AGREE BUTTON IF USER CHECK BOTH THE CHECKBOXES.
There is a problem with your logic of the QButton. You are storing the checked state in user defaults property isBtnChecked. But there are multiple instances of QButton (2 checkboxes), so even one is checked the property will be set to true. Avoid storing the state of the checkbox in defaults and instead query the state from checkBoxOne and checkBoxTwo using their is isChecked property.
Check if both check box button selected is true then update your agree botton accordingly.
If this button just contains text, you can use the code:
button.setTitleColor(UIColor.redColor(), forState: .Normal)
=> Take array for storing state of check button state. By default array contain "0" value for all elements , means if you have 5 checkboxes than array contain [#"0",#"0",#"0",#"0",#"0"] . now whenever button press , alter the state of button in array. so that if 2nd button pressed , and i have "0" state for that button than i replace "0" with "1" and check if array contain all "1" value than change the colour of agree button.
=> comment below if not understand any thing what i said.
I have a scrollview inside a view. Inside the scrollview I create programmatically 5 buttons. Every button loads a different image with a different tag each one. I added a function that is called when pressing the buttons.
let avatarsListScrollingView = avatarsListView(CGSizeMake(70.0, 55.0), avatarCount: 5)
func avatarsListView(buttonSize:CGSize, avatarCount:Int) -> UIView {
**CODE**
for i in 0...(avatarCount-1) {
let button = UIButton(type: .Custom)
**CODE**
button.setImage(UIImage(named: avatarsList[i]), forState: .Normal)
button.tag = i
button.addTarget(self, action: "avatarListSelected:", forControlEvents: .TouchUpInside)
avatarButtonView.addSubview(button)
}
return avatarButtonView
}
Then when pressing the buttons, I call to "avatarListSelected":
func avatarListSelected(sender:UIButton){
if let image = sender.imageView?.image?.imageWithRenderingMode(.AlwaysTemplate) {
sender.setImage(image, forState: .Normal)
sender.tintColor = UIColor.redColor()
}
self.addAvatarView.reloadInputViews()
}
This function tints the image button to red, it is working fine, but the problem is that when I press some other button, I want the other one goes to the original color. Right now every button that I press gets in red.
I tried to add the call to "self.addAvatarView.reloadInputViews()" to try to "redraw" again all the buttons, but never gets called.
Do you guys know some way to do this?
Thanks to everybody!
This is the final code that solved the problem:
func avatarListSelected(sender:UIButton){
print(sender.tag)
if let image = sender.imageView?.image?.imageWithRenderingMode(.AlwaysTemplate) {
sender.setImage(image, forState: .Normal)
sender.tintColor = UIColor.redColor()
}
for view in self.avatarButtonView.subviews as [UIView] {
if let btn = view as? UIButton {
if btn.tag != sender.tag {
btn.setImage(UIImage(named: avatarsList[btn.tag]), forState: .Normal)
}
}
}
}
Create a property selectedButton: UIButton? and keep a reference to the selected button there. Don't forget to update it in avatarListSelected method and before you change it, if it isn't nil, change its color to original (and then change it).
If the buttons have different original colors, subclass UIButton class and keep the original color there.
I don't know if is better approach or answer, but, i maybe could delivery this using this approach:
Create a method that will "fill" the color for your choice button and "clear" color to others , but its a method that loop through UIScrollView and look for each UIButton. Something like this :
func setBackgroundColorButton(color:UIColor , buttonTag:Int){
for view in self.scrollView.subviews as [UIView] {
if let btn = view as? UIButton {
if btn == buttonTag {
btn.tintColor = color
} else {
btn.tintColor = UIColor.whiteColor()
}
}
}
}
This is the concept, i didn't tested, but maybe just need adjust to search inside your scroll view or similar.
But with this will be work nice i believe :D
You could do it like this
for i in 0...5 {
let button = UIButton(type: .Custom)
let x = 50 * i + 10
let y = 50
button.frame = CGRectMake(CGFloat(x), CGFloat(y), 40, 40)
button.setTitle("\(i)", forState: .Normal)
button.tag = i
button.backgroundColor = UIColor.greenColor()
button.tintColor = UIColor.blueColor()
button.addTarget(self, action: "avatarListSelected:", forControlEvents: .TouchUpInside)
self.view.addSubview(button)
}
func avatarListSelected(sender : UIButton){
sender.backgroundColor = UIColor.orangeColor()
for view in self.view.subviews{
if(view.isKindOfClass(UIButton)){
let button = view as! UIButton
if button.tag != sender.tag{
button.backgroundColor = UIColor.greenColor()
}
}
}
}
The frame etc is just for demonstation purpose only, you should of course use your own value. The tintColor property is not valid for all button types. Read the documentation for more information.
I have a button in a tableview cell. I want that initially the button has an image "A", when the user clicks on it, it changes to "B", when the user clicks on it again it changes back to "A".
Let the two images to be "A" and "B" in this scenario
Wherever the button is:
button.addTarget(self, action: "pressed:", forControlEvents: .TouchUpInside)
button.setImage(UIImage(named: "a.png")!, forState: .Normal)
button.tag = 999
func pressed(sender: UIButton!) {
if sender.tag == 999 {
sender.setImage(UIImage(named: "b.png")!, forState: .Normal)
sender.tag = 0
} else {
sender.setImage(UIImage(named: "a.png")!, forState: .Normal)
sender.tag = 999
}
}
You can add tag to the button.
// This code comes in viewDidLoad
button.tag = 1 // for A
button.titleLabel.text = "A"
// On-click of the button, check the tag and change the name
if button.tag == 1
{
button.tag = 2
button.titleLabel.text = "B"
}
Subclass UIButton, add click handler in this class and make reference in Interface Builder. Then, create boolean property in your class, which you will trigger in click handler every time. In didSet of this property set proper image
If we are just dealing with two states then this solution is easier and less messy. You can simply use UIButton states.
You can assign different images for default state and selected state in storyboard itself.
func pressed(sender:UIButton){
sender.selected = !sender.selected
}
This will just change the states and images will be displayed depending on state.