Как создать радиокнопки и флажок в Swift (iOS)?

85

Я разрабатываю приложение, которое позволяет делать опросы. Мой макет создан из вопросов на основе XML.

Мне нужно создать переключатели (один вариант) и флажки (несколько ответов). Для swift ничего полезного не нашел.

Есть у кого-нибудь идеи?

Ванниан
источник
5
Вам нужно создать несколько кнопок с фоновым изображением в виде изображения CheckBox или изображения переключателя ... при нажатии кнопки изменить изображение как выбранное изображение ... должно быть два набора изображений, т.е. один выбран, другой
невыделено
2
Поскольку Xcode / iOS не предоставляет флажок / переключатель, я тоже использую то, что предлагает RJV.
Биста,
ага, пробовал, работает.
Vannian
Вы пробовали использовать библиотеки Cocoapods для флажков и переключателей?
Вимукти Раджапакша

Ответы:

40

Для радиокнопок и флажков нет ничего встроенного.

Вы можете легко реализовать флажки самостоятельно. Вы можете установить uncheckedImage для своей кнопки для UIControlStateNormal и checkedImage для своего UIControlStateSelected. Теперь при нажатии кнопка изменит свое изображение и будет переключаться между отмеченным и непроверенным изображением.

Чтобы использовать радиокнопки, вы должны оставить Arrayдля всех кнопок, которые вы хотите использовать как радиокнопки. Каждый раз, когда нажимается кнопка, вам необходимо снять отметку со всех других кнопок в массиве.

Для переключателей вы можете использовать SSRadioButtonsController. Вы можете создать объект контроллера и добавить к нему массив кнопок, например

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

Главный принцип здесь примерно такой .

Шамас С
источник
153

Флажок

Вы можете создать свой собственный элемент управления CheckBox, расширяющий UIButton с помощью 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
        }
    }
}

А затем добавьте его в свои представления с помощью Interface Builder:

введите описание изображения здесь

Радио-кнопки

Радио-кнопки решаются аналогичным образом.

Например, классический выбор пола Женщина - Мужчина :

введите описание изображения здесь

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
            }
        }
    }
}

Вы можете настроить свои переключатели следующим образом:

    override func awakeFromNib() {
        self.view.layoutIfNeeded()
        
        womanRadioButton.selected = true
        manRadioButton.selected = false
    }
    
    override func viewDidLoad() {
        womanRadioButton?.alternateButton = [manRadioButton!]
        manRadioButton?.alternateButton = [womanRadioButton!]
    }

Надеюсь, поможет.

Crubio
источник
1
для Swift 3 вам нужно изменить метод buttonClicked на func buttonClicked (_ sender: UIButton)
hilzj
1
при первом запуске я не вижу ни одного изображения с моим флажком ... оно появляется только после щелчка ... пожалуйста, помогите мне
H Raval
2
Привет, @Nitesh, вы можете получить статус Checked, используя публичное свойство bool isChecked, например: if myCheckbox.isChecked {...}
crubio
1
@ Jerland2 Понятия не имею, почему я не вижу вашего кода. Логическое значение isChecked связано с изображением, поэтому должно быть что-то еще.
crubio
1
@amorenew, если вы все еще ищете, как показать в построителе интерфейса, обратитесь к моему ответу.
Махендра Лия
22

Проверьте DLRadioButton . Вы можете добавлять и настраивать переключатели непосредственно из Интерфейсного разработчика. Также Swiftотлично работает с .

Swift Radio Button для iOS

Обновление: в версии 1.3.2добавлены квадратные кнопки, также улучшена производительность.

Обновление: в версии 1.4.4добавлена ​​опция множественного выбора, также может использоваться как флажок.

Обновление: в версию 1.4.7добавлена ​​поддержка языка RTL.

Дэвид Лю
источник
Я не понимаю, как использовать вашу кнопку в качестве флажка? у него есть только радио-кнопка?
dleviathan
1
Чтобы использовать его в качестве флажка, вы можете установить multipleSelectionEnabledи iconSquareна YES.
Дэвид Лю
1
Привет, @DavidLiu. Мне сложно внедрить вашу библиотеку в Swift 1.2. Я новичок в приложениях для iOS. Пропускает ли ваш ReadMe.md некоторые основные шаги? Я очень запуталась!
Милап 01
1
@milap Можете ли вы отправить вопрос и выложить образец кода?
Дэвид Лю
@DavidLiu Я заставил это работать, просто нужно было добавить ваш фреймворк во встроенные двоичные файлы. Может, захотите добавить этот шаг для супер новичков!
Milap 01
11

Swift 5, флажок с анимацией

Создаем розетку кнопки

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

Создайте расширение 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.8, y: 0.8)
            
        }) { (success) in
            UIView.animate(withDuration: 0.1, delay: 0, options: .curveLinear, animations: {
                self.isSelected = !self.isSelected
                //to-do
                closure()
                image.transform = .identity
            }, completion: nil)
        }
        
    }
}

Как пользоваться

 @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)
            
        }
}

Проверьте мой пример для флажка и переключателя https://github.com/rashidlatif55/CheckBoxAndRadioButton

Рашид Латиф
источник
2
Я думаю, это заслуживает большего количества голосов. Спасибо за элегантное решение.
Carlo
при нажатии на кнопку появляется синий квадрат. Как я могу сделать это круглым?
дану
1
@danu, чтобы сделать его круг, вы можете добавить эту строку в. didSet checkBoxOutlet.layer.cornerRadius = checkBoxOutlet.frame.height / 2И чтобы удалить синий цвет, tintкогда кнопка выбрана, вы можете добавить эту строку в расширение self.adjustsImageWhenHighlighted = false self.isHighlighted = false
Рашид Латиф
1
@danu Я создал для вас пример и предоставил ссылку в своем ответе. Вы можете поиграть с этим
Рашид Латиф
Таким образом , ответ , безусловно , заслуживает более вверх голосов благодаря @RashidLatif
Дана
9

Есть действительно отличная библиотека, которую вы можете использовать для этого (вы действительно можете использовать ее вместо UISwitch): https://github.com/Boris-Em/BEMCheckBox

Настройка проста:

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

Предусмотрены флажки круглого и квадратного типа.

введите описание изображения здесь

А еще делает анимацию:

введите описание изображения здесь

Кэлвин Элвин
источник
4

Очень простой элемент управления флажком.

 @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;
    }
}
Прагнеш Виттани
источник
4

короче версия ios swift 4:

@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
    }
Гульз
источник
1
этот ответ прост и дает тот же результат с меньшим количеством кода! +1
Джулиан Сильвестри
4

Решение для Radio Button в Swift 4.2 без использования сторонних библиотек

Создайте файл RadioButtonController.swift и поместите в него следующий код:

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
            }
        }
    }
}

Используйте его, как показано ниже, в файле контроллера представления:

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)
    }
}

Обязательно добавьте изображения radio_off и radio_on в Assets.

радио на изображении радио выключено изображение

Результат:

радио-кнопка результат

Ахилендра Сингх
источник
1
Аккуратное и многоразовое решение. Благодаря!
rak appdev
Точно !!! Это был более краткий ответ. Вне RadioButtonControllerэкземпляра я использовал проверку тега, selectedButtonчтобы отличить то, что было выбрано. Спасибо чувак!
Рандика Вишман
2

Шаги по созданию радиокнопки

BasicStep: возьмите две кнопки. установить изображение как для выбранного, так и для невыделенного. чем добавить действие к обеим кнопкам. теперь начните код

1) Создайте переменную:

var btnTag    : Int = 0

2) В ViewDidLoad определите:

 btnTag = btnSelected.tag

3) Теперь в выбранном действии касания:

 @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) Сделайте код для кнопки UnCheck

 @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
    }
}

Радиокнопка готова для вас

Крутарт Патель
источник
2

Для флажка не нужно создавать подкласс UIButton. У него уже есть isSelectedвозможность справиться с этим.

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)

Затем в методе действия переключите его isSelectedсостояние.

@objc func toggleCheckboxSelection() {
    checkbox.isSelected = !checkbox.isSelected
}
Салил Дхаван
источник
1

Вы можете просто создать подкласс UIButton и написать свой собственный код рисования в соответствии с вашими потребностями. Я реализовал радиокнопку, подобную той, что есть в android, используя следующий код. Его также можно использовать в раскадровке. См. Пример в репозитории Github

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()
    }
}
}
Никеш Джа
источник
1

Я сделал супер простой класс для решения этой проблемы в приложении Mac, над которым я работаю. Надеюсь, это кому-то поможет

RadioButtonController Класс:

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
        }
    }
}

}

Реализация в контроллере представления:

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
}

}
got2jam
источник
0
  1. Создайте 2 кнопки, одну как «ДА», а другую как «НЕТ».
  2. Создайте свойство BOOL Пример: isNRICitizen = false
  3. Назначьте одинаковую кнопку для обеих кнопок и установите тег (например: кнопка Да - тег 10 и кнопка Нет - тег 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)
}
Равиндра Кишан
источник
0

Для флажков есть встроенное решение в виде аксессуаров UITableViewCell. Вы можете настроить свою форму как UITableView, в котором каждая ячейка является выбираемым параметром и использовать accessoryTypeдля установки флажка для выбранных элементов.

Вот пример псевдокода:

    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()
    }

Однако радиокнопки требуют специальной реализации, см. Другие ответы.

Арон
источник
0

Решение о том, поставить или снять отметку с кнопки флажка, выходит за рамки представления. Само представление должно заботиться только о рисовании элементов, а не о их внутреннем состоянии. Моя предлагаемая реализация выглядит следующим образом:

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
    }
}

Его можно использовать с Interface Builder или программно. Использование представления может быть следующим примером:

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)
}
Сохейл Новинфард
источник
0

Swift 5.0 обновил Simple RadioButton для Swift (без библиотеки)

Сначала установите изображения на кнопку «Один установлен» и «Второй не отмечен».

Затем предоставьте 2 выхода RadioButton.

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

Создайте IBAction с действием обеих кнопок одним методом.

 @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)
    }

}
Threadripper
источник
0

У меня недостаточно репутации, чтобы давать комментарии, поэтому я оставлю здесь свою версию версии Салила Двахана . Работает для Swift 5, XCode 11.3.

Сначала поместите свою кнопку на IB, выберите тип «Custom» и создайте выход и действие с помощью макета помощника ( Ctrl+ перетаскивание). Включите следующий код, и он должен заканчиваться так:

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)
    }
}

Не забудьте добавить изображение в Assets и изменить имя, чтобы оно соответствовало!

checkbox.isSelected это способ проверить

Боско Доминго
источник
0

Хотя в некоторых ответах правильно упоминается, что мы можем использовать Selected State для установки изображения для выбранного состояния кнопки, это не будет работать элегантно, когда кнопка должна иметь и изображение, и текст.

Как и многие, я закончил тем, что создал подкласс UIButton; однако добавлена ​​поддержка установки изображений из Интерфейсного разработчика.

Ниже мой код:

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
        }
    }
}

Махендра Лия
источник