Unable to change image for the button in swift 3? - ios

In my code for checkmark I used button to change images for selected and unselected but unable to implement if I click on it's changing to unchecked but again selecting button it's unable to change to check image can anyone help me how to resolve this ?
var checkedImage = UIImage(named: "check")! as UIImage
var uncheckedImage = UIImage(named: "uncheck")! as UIImage
var isChecked: Bool = true
var checkMarkSelected = 0
checkMarkButton.addTarget(self, action: #selector(checkMarkAction(button:)), for: .touchUpInside)
func checkMarkAction(button : UIButton) {
if isChecked == true {
checkMarkButton.setImage(checkedImage, for: .selected)
isChecked = false
checkMarkSelected = 1
}
else {
checkMarkButton.setImage(uncheckedImage, for: .normal)
isChecked = true
checkMarkSelected = 0
}
}

Step 1: Select your CheckUIButton and set Image “Uncheck” (state config must be Default in attribute inspector)
Step 2: In attribute inspector change state config to Selected and set image “Check”
Step 3: Put following code in your UIButton action.
#IBAction func checkclick(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
}

In Swift 3
#IBAction func btntouchupInsideevent(_ sender: UIButton)
{
if yourbtnOutletName.currentImage == "YourCheckImageName"
{
yourbtnOutletName.setImage(YourUncheckImage.imagetype, for: .normal)
}
else
{
btnIsEventRecouring.setImage(YourcheckImage.imagetype, for: .normal)
}
}

I think that you should add the action in the viewDidLoad() function of your view controller for that button or, if you are declaring it in a stand-alone UIButton inherited class in order to reuse it in the future in many view controllers, you should add the target in the initialiser of the UIButton.
If the code is written in that way is even strange that Xcode is not giving you warnings...
EDIT: This is a code snippet of how I would do it
//Comments
import UIKit
class ViewController: UIViewController {
//link this to the checkmark buttons
//subclass UIButton making a button with the property isChecked: Bool
#IBOutlet weak var checkmarkButton: UICheckButton!
var checkMarkSelected = 0
override function viewDidLoad() {
//do stuff with your viewdidload
}
//link this to the checkmark buttons
#IBAction func checkMarkAction(sender: UICheckButton) {
if sender.isChecked == false {
let checkedImage = UIImage(named: "check")
checkMarkButton.setImage(checkedImage, for: .normal)
sender.isChecked = true
checkMarkSelected += checkMarkSelected
} else {
let uncheckedImage = UIImage(named: "uncheck")
checkMarkButton.setImage(uncheckedImage, for: .normal)
sender.isChecked = false
checkMarkSelected -= checkMarkSelected
}
}

In Swift 4:
#IBOutlet weak var termsAndConditionsButton: UIButton!
if termsAndConditionsButton.isSelected == true {
termsAndConditionsButton.setImage(UIImage(named: "checkboxOff"), for: .normal)
termsAndConditionsButton.isSelected=false
}
else{
termsAndConditionsButton.setImage(UIImage(named: "checkboxOn"), for: .normal)
termsAndConditionsButton.isSelected=true
}

Try with this on IBAction function
sender.isSelected = !sender.isSelected
if sender.isSelected == true {
sender.isSelected = true
sender.setImage(UIImage(named: "img_on"), for: UIControl.State.selected)
}else{
sender.isSelected = false
sender.setImage(UIImage(named: "img_off"), for: UIControl.State.normal)
}

Related

When I set Image inside a type of custom button (for normal), voice over mode is saying image name. How can I disable it for the button imageview?

I've created a custom button and set two images, one is for normal, and the other is for the selected mode. But the voice-over always says the normal image name text when the button is not selected. I've tried a lot but could not disable it.
When I disable the button imageView accessibility it is not working.
button.imageView?.isAccessibilityElement = false
When I disable the button accessibility, the voice-over is not working in accessibility mode.
button.isAccessibilityElement = false
If I remove the '.normal' mode image then it works, but normal mode image functionality is not considered/worked there. I'm surfing a lot. Help anyone and thanks in advance.
Code:
self.setImage(UIImage.init(named: imageName1), for: .normal)
self.setImage(UIImage.init(named: imageName1), for: .selected)
You can do it with a simple function, this is an example...
Declare your image and your button under controller class:
let newButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = .red
button.tintColor = .white
button.imageView?.contentMode = .scaleAspectFit
button.clipsToBounds = true
return button
}()
let image1 = UIImage(named: "magnifier") // image in my assets
let image2 = UIImage(named: "user") // image in my assets
in viewDidLoad addTarget to your button and call the control function, in my case:
handleCange()
newButton.addTarget(self, action: #selector(handleCange), for: .touchUpInside)
now set control variable and handleCange() func
var controlButtonState = false
#objc fileprivate func handleCange() {
if controlButtonState == true {
newButton.setImage(image1, for: .normal)
controlButtonState = false
} else {
newButton.setImage(image2, for: .normal)
controlButtonState = true
}
}
Basically, it is not possible indirect way. On the other hand we can use accessibilityLabel
I found an alternative solution. I think it is not a proper solution. Nonetheless, I am sharing this alternative solution. The question is open if anyone gets any proper solutions. Thanks!
import UIKit
struct RadioViewControllerConstant {
static let dayImage = "RadioButtonDontSelect"
static let dayImageSelected = "RadioButtonSelect"
}
class RadioViewController: UIViewController {
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
let image1 = UIImage(named: RadioViewControllerConstant.dayImageSelected)
let image2 = UIImage(named: RadioViewControllerConstant.dayImage)
var controlButtonState1 = false
var controlButtonState2 = false
override func viewDidLoad() {
super.viewDidLoad()
setVO()
}
func setVO() {
button1.accessibilityTraits = .none
button2.accessibilityTraits = .none
button1.isSelected = true
button2.isSelected = true
handleCange1()
handleCange2()
button1.addTarget(self, action: #selector(handleCange1), for: .touchUpInside)
button2.addTarget(self, action: #selector(handleCange2), for: .touchUpInside)
}
#objc fileprivate func handleCange1() {
if controlButtonState1 == true {
button1.imageView?.accessibilityLabel = "Radio button deselected"
button1.setImage(image2, for: .selected)
controlButtonState1 = false
} else {
button1.imageView?.accessibilityLabel = "Radio button selected"
button1.setImage(image1, for: .selected)
controlButtonState1 = true
}
}
#objc fileprivate func handleCange2() {
if controlButtonState2 == true {
button2.imageView?.accessibilityLabel = "Radio button deselected"
button2.setImage(image2, for: .selected)
controlButtonState2 = false
} else {
button2.imageView?.accessibilityLabel = "Radio button selected"
button2.setImage(image1, for: .selected)
controlButtonState2 = true
}
}
}

How to restrict button click

I have a VC like this
for the checkBoxes i have embedded UIButtons and i am changing their image on click. Here's my code
#IBOutlet weak var bestSellerButton: UIButton!
#IBOutlet weak var trendingButton: UIButton!
#IBOutlet weak var lowToHighButton: UIButton!
#IBOutlet weak var highToLowButton: UIButton!
var isBoxClicked = Bool()
func updateCheckImageOnClick(button: UIButton) {
if isBoxClicked == true {
isBoxClicked = false
button.setImage(UIImage.init(named: "checkmark"), for: UIControlState.normal)
}
else {
isBoxClicked = true
button.setImage(UIImage(), for: UIControlState.normal)
}
}
#IBAction func clickedBestSellerBtn(_ sender: Any) {
updateCheckImageOnClick(button: bestSellerButton)
}
#IBAction func clickedTrendingBtn(_ sender: Any) {
updateCheckImageOnClick(button: trendingButton)
}
likewise for the rest two. Now the check mark image is being set properly every time on click gets set and unset, but i want to restrict the user like if he clicks on best seller btn he's unable to choose the rest, likewise if he clicks trending he can't select any other. How would i do that?
Make the Other button disabled in particular scenario.
isUserInteractionEnabled = false
You could rename updateCheckImageOnClick(button: UIButton) to something generic in order to add some logic inside, like:
func update(button: UIButton) {
isBoxClicked = !isBoxClicked
button.setImage(isBoxClicked ? UIImage(named: "checkmark") : UIImage(), for: UIControlState.normal)
if button == bestSellerButton {
trendingButton.isEnabled = false
lowToHighButton.isEnabled = false
highToLowButton.isEnabled = false
} else if button == trendingButton {
bestSellerButton.isEnabled = false
lowToHighButton.isEnabled = false
highToLowButton.isEnabled = false
} else if button == highToLowButton {
trendingButton.isEnabled = false
lowToHighButton.isEnabled = false
bestSellerButton.isEnabled = false
} else {
bestSellerButton.isEnabled = false
trendingButton.isEnabled = false
highToLowButton.isEnabled = false
}
}
Usama I've implemented a simple button action for all those buttons which may accomplish your need. Here is the step by step implementation -
First, Declare these variables -
var buttonSelected:Bool = false
var selectedButton : UIButton?
Second, Add a single #IBAction for all buttons -
Third, Here is the action method -
#IBAction func btnSelection(_ sender: UIButton) {
if(buttonSelected){
if(selectedButton == sender){
buttonSelected = false
selectedButton = nil
sender.setImage(UIImage(), for: UIControlState.normal)
}
else{
// It's not the previously selected button
//Do your stuff
}
}
else{
buttonSelected = true
selectedButton = sender
sender.setImage(UIImage.init(named: "checkmark"), for: UIControlState.normal)
}
}
Hope it will help you to start with.

Toggle between select/deselect UIButton

I have a button which I want to change background color and text when tapped(select) and bring it back to its original state when tapped again (deselect). I am able to select it but I am not being able to deselect it. I have researched on SO and I am getting errors in this code in the if-else part
#IBAction func btn1Pressed(_ sender: AnyObject) {
sender.setTitleColor(UIColor.blue, for: UIControlState.normal)
(sender as! UIButton).backgroundColor = UIColor.green
if sender.isSelected {
sender.selected = false
}
else {
sender.selected = true
}
}
Try this:
#IBAction func btnPressed(_ sender: AnyObject) {
guard let button = sender as? UIButton else { return }
if !button.isSelected {
button.isSelected = true
button.setTitleColor(UIColor.blue, for: UIControl.State.normal)
button.backgroundColor = UIColor.green
}
else {
button.isSelected = false
button.setTitleColor(UIColor.green, for: UIControl.State.normal)
button.backgroundColor = UIColor.blue
}
}
It sounds to me like UISwitch is what you're looking for. Give it a try instead of wasting time implementing something that's already there for you.
try this
#IBAction func btn1Pressed(sender: UIButton) {
if sender.selected {
sender.selected = false
sender.setTitleColor(UIColor.redColor(), forState: .Normal)
sender.backgroundColor = UIColor.blackColor()
}
else {
sender.selected = true
sender.setTitleColor(UIColor.redColor(), forState: .Selected)
sender.backgroundColor = UIColor.blackColor()
}
}
Change background color of selected button from storyboard like below in state config choose selected and then change background color and also coustomize default for normal button.
and use below in action
(sender as! UIButton).selected = !(sender as! UIButton).selected
Please try this code first you need to crate action and propert of the button like
#IBOutlet var btn_ButtonPressed: UIButton!
then Action.
#IBAction func click_ButtonPressed(_ sender: Any) {
if !sender.isSelected() {
sender.selected = true
btn_ButtonPressed.setTitleColor(UIColor.red, forState: .normal)
btn_ButtonPressed.backgroundColor = UIColor.yellow
}
else {
sender.selected = false
btn_ButtonPressed.setTitleColor(UIColor.yellow, forState: .normal)
btn_ButtonPressed.backgroundColor = UIColor.red
}
}
this one worked fine for me!
//
#IBAction func buttonColorChanger(sender : UIButton ) {
if button.isSelected == false
{
button.backgroundColor = UIColor.purple
print("selected")
button.setTitle("selected", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.isSelected = true
}else{
button.backgroundColor = UIColor.white
print("unselected")
button.isSelected = false
}
}
A cleaner approach would be:
#objc private func buttonTapped(_ sender: UIButton) {
sender.isSelected.toggle()
if selected {
// Setup appearance for selected state.
} else {
// Setup appearance for deselected state.
}
}

Can not set set image for custom button

I'm going to implement a check box like this:
by
class CheckBox: UIButton {
let checkedImage = UIImage(named: "checked")
let uncheckedImage = UIImage(named: "unchecked")
var checked : Bool = false{
didSet{
if checked == false{
self.setImage(uncheckedImage, forState: .Normal)
}else {
self.setImage(checkedImage, forState: .Normal)
}
}
}
override func awakeFromNib() {
self.addTarget(self, action: "buttonClicked:", forControlEvents: .TouchUpInside)
checked = false
}
func buttonClicked(sender: UIButton){
if (sender == self){
checked = !checked
}
}
}
but everything I got is:
Could you explain what happened?
i tried your code it's works fine i only changed this part self.addTarget... to:
self.addTarget(self, action: #selector(CheckBox.buttonClicked(_:)), forControlEvents: .TouchUpInside)
and when you create the button change it class to: CheckBox
Call self.setNeedsLayout() at the end of your didSet statement.
If you change any of subviews you need to ask it to update it's layout and children. Let me know if that helped.

Set CheckBox on - off

I made a custom checkbox with button by creatin a class of UIButton
here is the class
import UIKit
class CheckBox: UIButton {
// Images
let checkedImage = UIImage(named: "ic_check_box")! as UIImage
let uncheckedImage = UIImage(named: "ic_check_box_outline_blank")! as UIImage
// Bool property
var isChecked: Bool = false {
didSet{
if isChecked == true {
self.setImage(checkedImage, forState: .Normal)
} else {
self.setImage(uncheckedImage, forState: .Normal)
}
}
}
override func awakeFromNib() {
self.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
self.isChecked = false
}
func buttonClicked(sender: UIButton) {
if sender == self {
isChecked = !isChecked
}
}
}
I have two checkboxes in the viewcontroller but I dont know how to set checkbox in the ViewController.class to do when checkBox "Si" is checked, the checkbox "No" set unchecked like in the image
Your CheckBox class should adopt a delegation pattern so that it can advise its delegate (which in this case would be your view controller) that its value has changed. Then in your view controller you can update the other checkbox as required:
protocol CheckBoxDelegate {
func checkBoxDidChange(checkbox: CheckBox) -> Void
}
class CheckBox: UIButton {
// Images
let checkedImage = UIImage(named: "ic_check_box")! as UIImage
let uncheckedImage = UIImage(named: "ic_check_box_outline_blank")! as UIImage
weak var delegate: CheckBoxDelegate?
// Bool property
var isChecked: Bool = false {
didSet{
if isChecked == true {
self.setImage(checkedImage, forState: .Normal)
} else {
self.setImage(uncheckedImage, forState: .Normal)
}
}
}
override func awakeFromNib() {
self.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
self.isChecked = false
}
func buttonClicked(sender: UIButton) {
isChecked = !isChecked
self.delegate?.checkBoxDidChange(self)
}
}
Then, in your View Controller:
class ViewController: UIViewController, CheckBoxDelegate {
#IBOutlet var siCheckBox: CheckBox! // Initialise some other way if you aren't using storyboard/nib
#IBOutlet var noCheckBox: CheckBox!
override func viewDidLoad() {
super.viewDidLoad()
self.siCheckBox.delegate = self
self.noCheckBox.delegate = self
}
//Mark: CheckBoxDelegate
func checkBoxDidChange(checkbox: CheckBox) {
if checkbox == self.siCheckBox {
self.noCheckBox.isChecked = !checkbox.isChecked
} else {
self.siCheckBox.isChecked = !checkbox.isChecked
}
}
From a user experience point of view, I would question why you need both checkboxes. A checkbox is an on/off control, so you would normally have text like "Select really great option?" with a single checkbox for yes/no; checked is yes, unchecked is no.
I would move func buttonClicked(sender: UIButton) to the parent ViewController.
let siCheckBox = CheckBox()
let noCheckBox = CheckBox()
func checkBoxToggled(sender: AnyObject) {
noCheckbox.isChecked = !noCheckbox.isChecked
siCheckbox.isChecked = !siCheckbox.isChecked
}
This is only safe if you're sure at least 1 is always checked. Otherwise I would add an if statement to make sure at l is checked.

Resources