How to create radio buttons and checkbox in swift (iOS)?
Asked Answered
L

21

109

I am developing an app that allows to do survey. My layout is generated from XML based questions.

I need to create radio buttons (single choice) and checkboxes (multiple answers). I did not find anything useful for swift.

Does anyone have an idea?

Loveland answered 18/3, 2015 at 9:1 Comment(5)
You need to create multiple buttons with background image as CheckBox image or radio button image...on click of button, change the image as selected image...should have two set of images, ie. one is selected, another for unselected..Monoceros
Since Xcode/iOS don't provide checkbox/radio button , i too use what RJV's suggested.Scrappy
yeh, I tried it, it is working.Loveland
Did you try to use Cocoapods libraries for checkboxes and radio buttons?Jaquenette
Regarding this very old question, it's now very easy. Answer added.Glyoxaline
T
45

For Radio Buttons and CheckBoxes there is nothing that comes built in.

You can implement Checkboxes easily yourself. You can set an uncheckedImage for your button for UIControlStateNormal and a checkedImage for your UIControlStateSelected. Now on tap, the button will change its image and alternate between checked and unchecked image.

To use radio buttons, you have to keep an Array for all the buttons that you want to behave as radio buttons. Whenever a button is pressed, you need to uncheck all other buttons in the array.

For radio buttons you can use SSRadioButtonsController You can create a controller object and add buttons array to it like

var radioButtonController = SSRadioButtonsController()
radioButtonController.setButtonsArray([button1!,button2!,button3!])

The main principle is something like this here.

Tenner answered 18/3, 2015 at 9:9 Comment(0)
A
171

Checkbox

You can create your own CheckBox control extending UIButton with Swift:

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, for: UIControl.State.normal)
            } else {
                self.setImage(uncheckedImage, for: UIControl.State.normal)
            }
        }
    }
        
    override func awakeFromNib() {
        self.addTarget(self, action:#selector(buttonClicked(sender:)), for: UIControl.Event.touchUpInside)
        self.isChecked = false
    }
        
    @objc func buttonClicked(sender: UIButton) {
        if sender == self {
            isChecked = !isChecked
        }
    }
}

And then add it to your views with Interface Builder:

enter image description here

Radio Buttons

Radio Buttons can be solved in a similar way.

For example, the classic gender selection Woman - Man:

enter image description here

import UIKit

class RadioButton: UIButton {
    var alternateButton:Array<RadioButton>?
    
    override func awakeFromNib() {
        self.layer.cornerRadius = 5
        self.layer.borderWidth = 2.0
        self.layer.masksToBounds = true
    }
    
    func unselectAlternateButtons() {
        if alternateButton != nil {
            self.isSelected = true
            
            for aButton:RadioButton in alternateButton! {
                aButton.isSelected = false
            }
        } else {
            toggleButton()
        }
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        unselectAlternateButtons()
        super.touchesBegan(touches, with: event)
    }
    
    func toggleButton() {
        self.isSelected = !isSelected
    }
    
    override var isSelected: Bool {
        didSet {
            if isSelected {
                self.layer.borderColor = Color.turquoise.cgColor
            } else {
                self.layer.borderColor = Color.grey_99.cgColor
            }
        }
    }
}

You can init your radio buttons like this:

    override func awakeFromNib() {
        self.view.layoutIfNeeded()
        
        womanRadioButton.selected = true
        manRadioButton.selected = false
    }
    
    override func viewDidLoad() {
        womanRadioButton?.alternateButton = [manRadioButton!]
        manRadioButton?.alternateButton = [womanRadioButton!]
    }
Autonomic answered 4/11, 2015 at 10:15 Comment(23)
how to show it in interface builder like this ? developer.apple.com/library/ios/recipes/…Paint
is there any reason that you used func buttonClicked(sender: UIButton) { if sender == self { if isChecked == true { isChecked = false } else { isChecked = true } } } instead of: func ButtonClicked(sender: UIButton) { if sender == self {isChecked = !isChecked} }Rhombus
If you want to use text only then use this "✓" when check "" when unchecked.Diarist
hi crubio . for radio buttons how can I create custom class and howz its implementation@AutonomicLothians
for Swift 3 you need to change buttonClicked method to func buttonClicked(_ sender: UIButton)Sufflate
what if i have only one button in my tableview cellPickaback
at first run i can't see any image with my checkbox...it only appear after click...please help meHausmann
@Autonomic How to get the Checked status from other VC ?Stravinsky
Hi @Stravinsky you can get the Checked status using the public bool property isChecked, for example: if myCheckbox.isChecked { ... }Autonomic
Why did you use sender == self??Than
@MukulMore sender parameter is just to determine which button was pressed. In this case we only care about our button (checkbox)Autonomic
@Autonomic i think sender == self will always be true ..can you tell me a case in which it returns false.Than
Yes @MukulMore it's a protection condition, the code would work without itAutonomic
@Jerland2 No idea why without seeing any of your code. The boolean isChecked is connected to the image so there must be something else.Autonomic
@Autonomic You are correct, rough morning missed a line of code I had in another VC that conflicted... Problem solved, thanks for a reply though! Edit: Deleted orig comment to avoid confusion for later viewersCozart
@Autonomic How to get selected button text or title?Jellyfish
@B.SaravanaKumar you can use button.titleLabel.textAutonomic
But I created buttons dynamically , that buttons increments based on array counts in for loop, then how to get title..Jellyfish
It might be useful to call sendActions(for: .valueChanged) when the checkbox changes state, so that any targets listening to that event get notified.Teocalli
Please note, that you need to add the @objc annotation to the func buttonClicked( sender: UIButton) methodSavanna
I am actually using the radiobutton in my SwiftCode, but it is actually not showing on my view...but i can see the radioButton text. I will really appreciate an insight to this pls.Endamage
@Paint if you are still looking for how to show in interface builder, please refer to my answer.Darky
This is a great answer from a decade ago, I've updated it and added the line of code needed to make radio buttons if you also need radio buttons.Glyoxaline
T
45

For Radio Buttons and CheckBoxes there is nothing that comes built in.

You can implement Checkboxes easily yourself. You can set an uncheckedImage for your button for UIControlStateNormal and a checkedImage for your UIControlStateSelected. Now on tap, the button will change its image and alternate between checked and unchecked image.

To use radio buttons, you have to keep an Array for all the buttons that you want to behave as radio buttons. Whenever a button is pressed, you need to uncheck all other buttons in the array.

For radio buttons you can use SSRadioButtonsController You can create a controller object and add buttons array to it like

var radioButtonController = SSRadioButtonsController()
radioButtonController.setButtonsArray([button1!,button2!,button3!])

The main principle is something like this here.

Tenner answered 18/3, 2015 at 9:9 Comment(0)
D
37

Swift 5, Checkbox with animation

NOTE:- if you want to remove the blue background while isSelected change the UIButton type from System to Custom

Check my Example for the Checkbox and Radio button https://github.com/rashidlatif55/CheckBoxAndRadioButton

Create an outlet for the button

@IBOutlet weak var checkBoxOutlet:UIButton!{
        didSet{
            checkBoxOutlet.setImage(UIImage(named:"unchecked"), for: .normal)
            checkBoxOutlet.setImage(UIImage(named:"checked"), for: .selected)
        }
    }

Create an extension of UIButton

extension UIButton {
    //MARK:- Animate check mark
    func checkboxAnimation(closure: @escaping () -> Void){
        guard let image = self.imageView else {return}
        
        UIView.animate(withDuration: 0.1, delay: 0.1, options: .curveLinear, animations: {
            image.transform = CGAffineTransform(scaleX: 0.85, y: 0.85)
            
        }) { (success) in
            UIView.animate(withDuration: 0.1, delay: 0, options: .curveLinear, animations: {
                self.isSelected = !self.isSelected
                //to-do
                closure()
                image.transform = .identity
            }, completion: nil)
        }
        
    }
}

How to use

 @IBAction func checkbox(_ sender: UIButton){
        sender.checkboxAnimation {
            print("I'm done")
            //here you can also track the Checked, UnChecked state with sender.isSelected
            print(sender.isSelected)
            
        }
}
Disendow answered 17/12, 2019 at 7:28 Comment(7)
I think this deserves more votes. Thanks for the elegant solution.Clumsy
i get a blue square when i select the button. How can i make it circularPerturb
@Perturb to make it circle you can add this line in didSet checkBoxOutlet.layer.cornerRadius = checkBoxOutlet.frame.height / 2 And to remove the blue tint when the button is selected you can add these line in extension self.adjustsImageWhenHighlighted = false self.isHighlighted = falseDisendow
@Perturb I have created and Example for you, and provide a link in my answer. You can play with thatDisendow
thus answer definitely deserve more up votes thanks @RashidLatifPerturb
small thing i noticed was setting the "checkBoxOutlet.layer.cornerRadius" would not make the inner circle round (the state when u select). only making the button roundPerturb
Thank you @RashidLatif . elegant solutionArtima
V
23

Check out DLRadioButton. You can add and customize radio buttons directly from the Interface Builder. Also works with Swift perfectly.

Swift Radio Button for iOS

Update: version 1.3.2 added square buttons, also improved performance.

Update: version 1.4.4 added multiple selection option, can be used as checkbox as well.

Update: version 1.4.7 added RTL language support.

Vanpelt answered 1/7, 2015 at 23:47 Comment(13)
I don't see how to use your button as checkbox? it only have radio button?Insnare
To use it as checkbox, you can set multipleSelectionEnabled and iconSquare to YES.Vanpelt
Hey @DavidLiu I'm having a hard time implementing your library to swift 1.2. I'm very new to Ios apps, is your ReadMe.md skipping some basic steps? I'm very confused!Eo
@milap Can you submit an issue and put out sample code?Vanpelt
@DavidLiu I got it to work, just needed to add your framework to Embedded Binaries. May want to add that step for the super beginners!Eo
@DavidLiu : I can't get it work. I use option 2, but starting from step 3, I don't see any of the options depicted in your screencaps. I think I'm mising something here since I'm very new to ios. And I'm not sure what Milap means by adding framework to embedded binaries. Do I still need to download .h and .m file? But I'm using swift 1.2 though.Argive
Just in case anybody have hard time adding library..just follow the steps from this site - raywenderlich.com/97014/use-cocoapods-with-swiftArgive
How can i implement your button in tableview cell where i can use only one button per row?? Your library works only if there are multiple buttons.. but i have only one cell in my tableview. How do I make it work??Pickaback
@Pickaback Sorry, I don't quite understand your question. DLRadioButton should work regardless you put it in a table view cell or other UIViews.Vanpelt
For all those having confusions using this library here is a well explained tutorial. simplifiedios.net/xcode-radio-button-exampleFlywheel
This is a poorly implemented library.Petry
The RTL support don't really work because when the app is in RTL the marginWith prop don't work anymore. I do have a workaround by adding a titleEdgeInsets to button's title like this: checkButton.titleEdgeInsets = UIEdgeInsets(top: 0,left: 0,bottom: 0,right: 10)Montpelier
Does not support Swift Package Manager, years on...Elea
C
16

Solution for Radio Button in Swift 4.2 without using third-party libraries

Create RadioButtonController.swift file and place following code in it:

import UIKit

class RadioButtonController: NSObject {
    var buttonsArray: [UIButton]! {
        didSet {
            for b in buttonsArray {
                b.setImage(UIImage(named: "radio_off"), for: .normal)
                b.setImage(UIImage(named: "radio_on"), for: .selected)
            }
        }
    }
    var selectedButton: UIButton?
    var defaultButton: UIButton = UIButton() {
        didSet {
            buttonArrayUpdated(buttonSelected: self.defaultButton)
        }
    }

    func buttonArrayUpdated(buttonSelected: UIButton) {
        for b in buttonsArray {
            if b == buttonSelected {
                selectedButton = b
                b.isSelected = true
            } else {
                b.isSelected = false
            }
        }
    }
}

Use it as below in your view controller file:

import UIKit

class CheckoutVC: UIViewController {

    @IBOutlet weak var btnPaytm: UIButton!
    @IBOutlet weak var btnOnline: UIButton!
    @IBOutlet weak var btnCOD: UIButton!

    let radioController: RadioButtonController = RadioButtonController()

    override func viewDidLoad() {
        super.viewDidLoad()

        radioController.buttonsArray = [btnPaytm,btnCOD,btnOnline]
        radioController.defaultButton = btnPaytm
    }

    @IBAction func btnPaytmAction(_ sender: UIButton) {
        radioController.buttonArrayUpdated(buttonSelected: sender)
    }

    @IBAction func btnOnlineAction(_ sender: UIButton) {
        radioController.buttonArrayUpdated(buttonSelected: sender)
    }

    @IBAction func btnCodAction(_ sender: UIButton) {
        radioController.buttonArrayUpdated(buttonSelected: sender)
    }
}

Be sure to add radio_off and radio_on images in Assets.

radio on image radio off image

Result:

radio button result

Cum answered 5/5, 2020 at 13:42 Comment(2)
Neat and reusable solution. Thanks!Bridie
Precise!!! This was more consize answer. Out of the RadioButtonController instance, I used checking out the tag of selectedButton to distinguish what's been selected. Thanks man!Randallrandan
M
8

There's a really great library out there you can use for this (you can actually use this in place of UISwitch): https://github.com/Boris-Em/BEMCheckBox

Setup is easy:

BEMCheckBox *myCheckBox = [[BEMCheckBox alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
[self.view addSubview:myCheckBox];

It provides for circle and square type checkboxes

enter image description here

And it also does animations:

enter image description here

Mauve answered 14/4, 2017 at 21:6 Comment(0)
C
6

shorter ios swift 4 version:

@IBAction func checkBoxBtnTapped(_ sender: UIButton) {
        if checkBoxBtn.isSelected {
            checkBoxBtn.setBackgroundImage(#imageLiteral(resourceName: "ic_signup_unchecked"), for: .normal)
        } else {
            checkBoxBtn.setBackgroundImage(#imageLiteral(resourceName: "ic_signup_checked"), for:.normal)
        }
        checkBoxBtn.isSelected = !checkBoxBtn.isSelected
    }
Cockaleekie answered 24/10, 2017 at 12:30 Comment(1)
this answer is simple and achieves the same outcome with less code! +1Effable
A
5

A very simple checkbox control.

 @IBAction func btn_box(sender: UIButton) {
    if (btn_box.selected == true)
    {
        btn_box.setBackgroundImage(UIImage(named: "box"), forState: UIControlState.Normal)

            btn_box.selected = false;
    }
    else
    {
        btn_box.setBackgroundImage(UIImage(named: "checkBox"), forState: UIControlState.Normal)

        btn_box.selected = true;
    }
}
Arrogance answered 25/11, 2016 at 10:27 Comment(0)
I
4

For a checkbox, you don't need to subclass the UIButton. It already has the isSelected property to handle this.

checkbox = UIButton.init(type: .custom)
checkbox.setImage(UIImage.init(named: "iconCheckboxOutlined"), for: .normal)
checkbox.setImage(UIImage.init(named: "iconCheckboxFilled"), for: .selected)
checkbox.addTarget(self, action: #selector(self.toggleCheckboxSelection), for: .touchUpInside)

Then in the action method toggle it's isSelected state.

@objc func toggleCheckboxSelection() {
    checkbox.isSelected = !checkbox.isSelected
}
Iridosmine answered 21/10, 2018 at 2:23 Comment(1)
This answer is so simple without subclassing anything. Works perfectly!Selfsuggestion
P
3

Steps to Create Radio Button

BasicStep : take Two Button. set image for both like selected and unselected. than add action to both button. now start code

1)Create variable :

var btnTag    : Int = 0

2)In ViewDidLoad Define :

 btnTag = btnSelected.tag

3)Now In Selected Tap Action :

 @IBAction func btnSelectedTapped(sender: AnyObject) {
    btnTag = 1
    if btnTag == 1 {
      btnSelected.setImage(UIImage(named: "icon_radioSelected"), forState: .Normal)
      btnUnSelected.setImage(UIImage(named: "icon_radioUnSelected"), forState: .Normal)
     btnTag = 0
    }
}

4)Do code for UnCheck Button

 @IBAction func btnUnSelectedTapped(sender: AnyObject) {
    btnTag = 1
    if btnTag == 1 {
        btnUnSelected.setImage(UIImage(named: "icon_radioSelected"), forState: .Normal)
        btnSelected.setImage(UIImage(named: "icon_radioUnSelected"), forState: .Normal)
        btnTag = 0
    }
}

Radio Button is Ready for you

Physiotherapy answered 12/8, 2016 at 7:0 Comment(0)
Y
2

You can simply subclass UIButton and write your own drawing code to suit your needs. I implemented a radio button like that of android using the following code. It can be used in storyboard as well.See example in Github repo

import UIKit

@IBDesignable
class SPRadioButton: UIButton {

@IBInspectable
var gap:CGFloat = 8 {
    didSet {
        self.setNeedsDisplay()
    }
}

@IBInspectable
var btnColor: UIColor = UIColor.green{
    didSet{
        self.setNeedsDisplay()
    }
}

@IBInspectable
var isOn: Bool = true{
    didSet{
        self.setNeedsDisplay()
    }
}

override func draw(_ rect: CGRect) {
    self.contentMode = .scaleAspectFill
    drawCircles(rect: rect)
}


//MARK:- Draw inner and outer circles
func drawCircles(rect: CGRect){
    var path = UIBezierPath()
    path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: rect.width, height: rect.height))

    let circleLayer = CAShapeLayer()
    circleLayer.path = path.cgPath
    circleLayer.lineWidth = 3
    circleLayer.strokeColor = btnColor.cgColor
    circleLayer.fillColor = UIColor.white.cgColor
    layer.addSublayer(circleLayer)

    if isOn {
        let innerCircleLayer = CAShapeLayer()
        let rectForInnerCircle = CGRect(x: gap, y: gap, width: rect.width - 2 * gap, height: rect.height - 2 * gap)
        innerCircleLayer.path = UIBezierPath(ovalIn: rectForInnerCircle).cgPath
        innerCircleLayer.fillColor = btnColor.cgColor
        layer.addSublayer(innerCircleLayer)
    }
    self.layer.shouldRasterize =  true
    self.layer.rasterizationScale = UIScreen.main.nativeScale
}

/*
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    isOn = !isOn
    self.setNeedsDisplay()
}
*/    

override func awakeFromNib() {
    super.awakeFromNib()
    addTarget(self, action: #selector(buttonClicked(sender:)), for: UIControl.Event.touchUpInside)
    isOn = false
}

@objc func buttonClicked(sender: UIButton) {
    if sender == self {
        isOn = !isOn
        setNeedsDisplay()
    }
}
}
Ylangylang answered 3/1, 2018 at 10:6 Comment(0)
T
2

I made a super simple class to handle this in a Mac application I'm working on. Hopefully, this is helpful to someone

RadioButtonController Class:

class RadioButtonController: NSObject {

var buttonArray : [NSButton] = []
var currentleySelectedButton : NSButton?
var defaultButton : NSButton = NSButton() {
    didSet {
        buttonArrayUpdated(buttonSelected: self.defaultButton)
    }
}

func buttonArrayUpdated(buttonSelected : NSButton) {
    for button in buttonArray {
        if button == buttonSelected {
            currentleySelectedButton = button
            button.state = .on
        } else {
            button.state = .off
        }
    }
}

}

Implementation in View Controller:

class OnboardingDefaultLaunchConfiguration: NSViewController {

let radioButtonController : RadioButtonController = RadioButtonController()
@IBOutlet weak var firstRadioButton: NSButton!
@IBOutlet weak var secondRadioButton: NSButton!

@IBAction func folderRadioButtonSelected(_ sender: Any) {
    radioButtonController.buttonArrayUpdated(buttonSelected: folderGroupRadioButton)
}

@IBAction func fileListRadioButtonSelected(_ sender: Any) {
    radioButtonController.buttonArrayUpdated(buttonSelected: fileListRadioButton)
}

override func viewDidLoad() {
    super.viewDidLoad()
    radioButtonController.buttonArray = [firstRadioButton, secondRadioButton]
    radioButtonController.defaultButton = firstRadioButton
}

}
Teapot answered 18/3, 2020 at 13:10 Comment(0)
M
1

For checkboxes there is actually a built-in solution in the form of UITableViewCell accessories. You can set up your form as a UITableView in which each cell as a selectable option and use accessoryType to set a check mark for selected items.

Here is a pseudo-code example:

    let items = [SelectableItem]

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        // Get the item for the current row
        let item = self.items[indexPath.row]

        // ...dequeue and set up the `cell` as you wish...

        // Use accessoryType property to mark the row as checked or not...
        cell.accessoryType = item.selected ? .checkmark : .none
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        // Unselect row
        tableView.deselectRow(at: indexPath, animated: false)

        // Toggle selection
        let item = self.items[indexPath.row]
        item.selected = !item.selected
        tableView.reloadData()
    }

Radio buttons however do require a custom implementation, see the other answers.

Mcnully answered 8/2, 2019 at 14:39 Comment(0)
H
1

The decision of checking or unchecking the checkbox button is something out of the scope of the view. View itself should only take care of drawing the elements, not deciding about the internal state of that. My suggested implementation is as follows:

import UIKit

class Checkbox: UIButton {

    let checkedImage = UIImage(named: "checked")
    let uncheckedImage = UIImage(named: "uncheked")
    var action: ((Bool) -> Void)? = nil

    private(set) var isChecked: Bool = false {
        didSet{
            self.setImage(
                self.isChecked ? self.checkedImage : self.uncheckedImage,
                for: .normal
            )
        }
    }

    override func awakeFromNib() {
        self.addTarget(
            self,
            action:#selector(buttonClicked(sender:)),
            for: .touchUpInside
        )
        self.isChecked = false
    }

    @objc func buttonClicked(sender: UIButton) {
        if sender == self {
            self.action?(!self.isChecked)
        }
    }

    func update(checked: Bool) {
        self.isChecked = checked
    }
}

It can be used with Interface Builder or programmatically. The usage of the view could be as the following example:

let checkbox_field = Checkbox(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
checkbox_field.action = { [weak checkbox_field] checked in
    // any further checks and business logic could be done here
    checkbox_field?.update(checked: checked)
}
Hardin answered 9/5, 2019 at 17:3 Comment(0)
A
1

I don't have enough reputation to comment, so I'll leave my version of Salil Dwahan's version here. Works for Swift 5, XCode 11.3.

First place your button on IB, select type "Custom" and create an outlet and an action with the Assistant Layout (Ctrl + Drag). Include the following code and it should end like this:

class YourViewController: UIViewController {
    @IBOutlet weak var checkbox: UIButton!
    @IBAction func checkboxTapped(_ sender: UIButton) {
        checkbox.isSelected = !checkbox.isSelected
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        checkbox.setImage(UIImage.init(named: "checkMark"), for: .selected)
    }
}

Don't forget to add the image to Assets and change the name to match!

checkbox.isSelected is the way to check

Arenaceous answered 2/1, 2020 at 14:30 Comment(0)
D
1

Though some of the answers mention it rightly that we can use the Selected State to set an image for Selected state of the button, it won't work elegantly when the button has to have both image and text.

Like many, I ended by subclassing UIButton; however, added support for setting images from Interface Builder.

Below is my code:

import UIKit

class CustomCheckbox: UIButton {

    @IBInspectable var defaultStateImage: UIImage? = nil {
        didSet{
            self.setNeedsDisplay()
        }
    }

    @IBInspectable var selectedStateImage: UIImage? = nil {
        didSet{
            self.setNeedsDisplay()
        }
    }

    @IBInspectable var gapPadding: CGFloat = 0 {
        didSet{
            self.setNeedsDisplay()
        }
    }

    @IBInspectable var isChecked: Bool = false {
        didSet{
            self.setNeedsDisplay()
        }
    }

    var defaultImageView: UIImageView? = nil
    var selectedImageView: UIImageView? = nil

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        setup()
    }

    func setup() {
        if(defaultStateImage != nil) {
            defaultImageView = UIImageView(image: defaultStateImage)
            defaultImageView?.translatesAutoresizingMaskIntoConstraints = false

            addSubview(defaultImageView!)

            let length = CGFloat(16)
            titleEdgeInsets.left += length

            NSLayoutConstraint.activate([
                defaultImageView!.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: -gapPadding),
                defaultImageView!.centerYAnchor.constraint(equalTo: self.titleLabel!.centerYAnchor, constant: 0),
                defaultImageView!.widthAnchor.constraint(equalToConstant: length),
                defaultImageView!.heightAnchor.constraint(equalToConstant: length)
            ])
        }

        if(selectedStateImage != nil) {
            selectedImageView = UIImageView(image: selectedStateImage)
            selectedImageView!.translatesAutoresizingMaskIntoConstraints = false

            addSubview(selectedImageView!)

            let length = CGFloat(16)
            titleEdgeInsets.left += length

            NSLayoutConstraint.activate([
                selectedImageView!.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: -gapPadding),
                selectedImageView!.centerYAnchor.constraint(equalTo: self.titleLabel!.centerYAnchor, constant: 0),
                selectedImageView!.widthAnchor.constraint(equalToConstant: length),
                selectedImageView!.heightAnchor.constraint(equalToConstant: length)
            ])
        }

        if defaultImageView != nil {
            defaultImageView!.isHidden = isChecked
        }

        if selectedImageView != nil  {
            selectedImageView!.isHidden = !isChecked
        }

        self.addTarget(self, action: #selector(checkChanged(_:)), for: .touchUpInside)
    }

    @objc func checkChanged(_ btn : UIButton){
        self.isChecked = !self.isChecked

        if defaultImageView != nil {
            defaultImageView!.isHidden = isChecked
        }

        if selectedImageView != nil  {
            selectedImageView!.isHidden = !isChecked
        }
    }
}

Darky answered 24/5, 2020 at 14:6 Comment(0)
S
0
  1. Create 2 buttons one as "YES" and another as "NO".
  2. Create a BOOL property Ex: isNRICitizen = false
  3. Give same button connection to both the buttons and set a tag (Ex: Yes button - tag 10 and No button -tag 20)
@IBAction func btnAction(_ sender:UIButton) {

isNRICitizen = sender.tag == 10 ? true : false
isNRICitizen ? self.nriCitizenBtnYes.setImage(#imageLiteral(resourceName: "radioChecked"), for: .normal) : self.nriCitizenBtnYes.setImage(#imageLiteral(resourceName: "radioUnchecked"), for: .normal)
        isNRICitizen ? self.nriCitizenBtnNo.setImage(#imageLiteral(resourceName: "radioUnchecked"), for: .normal) : self.nriCitizenBtnNo.setImage(#imageLiteral(resourceName: "radioChecked"), for: .normal)
}
Saretta answered 4/2, 2019 at 6:59 Comment(0)
N
0

Swift 5.0 Updated Simple RadioButton For Swift (No Library)

First set images to button One Checked and Second Unchecked.

Then Provide 2 Outlet Of RadioButton.

@IBOutlet weak var radioMale: UIButton!
@IBOutlet weak var radioFemale: UIButton!

Create IBAction With Both Button Action in One Method.

 @IBAction func btnRadioTapped(_ sender: UIButton) {

    radioMale.setImage(UIImage(named: "Unchecked"), for: .normal)
    radioFemale.setImage(UIImage(named: "Unchecked"), for: .normal)

    if sender.currentImage == UIImage(named: "Unchecked"){

        sender.setImage(UIImage(named: "Checked"), for: .normal)

    }else{

        sender.setImage(UIImage(named: "Unchecked"), for: .normal)
    }

}
Nolannolana answered 28/11, 2019 at 10:11 Comment(0)
C
0

Couldn't find an easy SwiftUI version in this thread so here is a quick component using SF symbols.

struct CheckBox: View {

  private let checked = Image("checkmark.square.fill")
  private let unChecked = Image("checkmark.square")
  @State private var isChecked: Bool = false

  var body: some View {
      ZStack {
          isChecked == false ? unChecked : checked
       }.onTapGesture {
          isChecked.toggle()
       }   
   }
}
Conservator answered 24/8, 2021 at 5:41 Comment(0)
E
0

If you use Image when change state. Try this:

 var nightButtonState: Bool = false {
     didSet {
         nightButtonState ? autoNightButton.setBackgroundImage(UIImage(named: "unchecked_icon"), for: .normal) : autoNightButton.setBackgroundImage(UIImage(named: "checked_icon"), for: .normal)
     } 
  }

Button action:

@IBAction func autoNightButtonAction(_ sender: UIButton) {
  self.nightButtonState.toggle()
}
Edie answered 15/9, 2022 at 22:17 Comment(0)
G
0

The very easy way to create a check box in modern Xcode/UIKit, using storyboard.

1. Simply make a checked button, any way you wish, on storyboard.

This is very easy with the modern button options and SF Symbols.

Example,

enter image description here enter image description here

Do anything you want so it looks how you want it.

2. Simply change the UIButton to this class ...

///Checkbox with `.checked` property.
class CheckBox: UIButton {
    
    var checked: Bool = false {
        didSet { imageView?.isHidden = !checked }
    }
        
    override func awakeFromNib() {
        addTarget(self, action: #selector(clicked(sender:)), for: .primaryActionTriggered)
        checked = false
    }
        
    @objc func clicked(sender: UIButton) {
        if sender == self { checked = !checked }
    }
}

That's the whole thing.

To make a set of radio buttons.

It's very simple, in the didSet code, just add code such as

...
imageView?.isHidden = !checked
if checked {
  superview?.subviews.filter{ $0 is CheckBox && $0 != self}
    .forEach{$0.checked = false}
}

In English, "If I'm now checked, for each of my siblings which is a CheckBox, simply set them to checked."

Glyoxaline answered 6/12, 2023 at 17:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.