Вам нужно создать несколько кнопок с фоновым изображением в виде изображения CheckBox или изображения переключателя ... при нажатии кнопки изменить изображение как выбранное изображение ... должно быть два набора изображений, т.е. один выбран, другой
невыделено
2
Поскольку Xcode / iOS не предоставляет флажок / переключатель, я тоже использую то, что предлагает RJV.
Биста,
ага, пробовал, работает.
Vannian
Вы пробовали использовать библиотеки Cocoapods для флажков и переключателей?
Вимукти Раджапакша
Ответы:
40
Для радиокнопок и флажков нет ничего встроенного.
Вы можете легко реализовать флажки самостоятельно. Вы можете установить uncheckedImage для своей кнопки для UIControlStateNormal и checkedImage для своего UIControlStateSelected. Теперь при нажатии кнопка изменит свое изображение и будет переключаться между отмеченным и непроверенным изображением.
Чтобы использовать радиокнопки, вы должны оставить Arrayдля всех кнопок, которые вы хотите использовать как радиокнопки. Каждый раз, когда нажимается кнопка, вам необходимо снять отметку со всех других кнопок в массиве.
Для переключателей вы можете использовать SSRadioButtonsController.
Вы можете создать объект контроллера и добавить к нему массив кнопок, например
var radioButtonController = SSRadioButtonsController()
radioButtonController.setButtonsArray([button1!,button2!,button3!])
для 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отлично работает с .
Обновление: в версии 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 Я заставил это работать, просто нужно было добавить ваш фреймворк во встроенные двоичные файлы. Может, захотите добавить этот шаг для супер новичков!
@IBActionfunccheckbox(_ sender: UIButton){
sender.checkboxAnimation {
print("I'm done")
//here you can also track the Checked, UnChecked state with sender.isSelectedprint(sender.isSelected)
}
}
Я думаю, это заслуживает большего количества голосов. Спасибо за элегантное решение.
Carlo
при нажатии на кнопку появляется синий квадрат. Как я могу сделать это круглым?
дану
1
@danu, чтобы сделать его круг, вы можете добавить эту строку в. didSetcheckBoxOutlet.layer.cornerRadius = checkBoxOutlet.frame.height / 2И чтобы удалить синий цвет, tintкогда кнопка выбрана, вы можете добавить эту строку в расширение self.adjustsImageWhenHighlighted = false self.isHighlighted = false
Рашид Латиф
1
@danu Я создал для вас пример и предоставил ссылку в своем ответе. Вы можете поиграть с этим
Рашид Латиф
Таким образом , ответ , безусловно , заслуживает более вверх голосов благодаря @RashidLatif
Дана
9
Есть действительно отличная библиотека, которую вы можете использовать для этого (вы действительно можете использовать ее вместо UISwitch): https://github.com/Boris-Em/BEMCheckBox
Точно !!! Это был более краткий ответ. Вне RadioButtonControllerэкземпляра я использовал проверку тега, selectedButtonчтобы отличить то, что было выбрано. Спасибо чувак!
Рандика Вишман
2
Шаги по созданию радиокнопки
BasicStep: возьмите две кнопки. установить изображение как для выбранного, так и для невыделенного. чем добавить действие к обеим кнопкам. теперь начните код
Вы можете просто создать подкласс UIButton и написать свой собственный код рисования в соответствии с вашими потребностями. Я реализовал радиокнопку, подобную той, что есть в android, используя следующий код. Его также можно использовать в раскадровке. См. Пример в репозитории Github
Для флажков есть встроенное решение в виде аксессуаров UITableViewCell. Вы можете настроить свою форму как UITableView, в котором каждая ячейка является выбираемым параметром и использовать accessoryTypeдля установки флажка для выбранных элементов.
Вот пример псевдокода:
let items = [SelectableItem]
functableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Get the item for the current rowlet 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
}
functableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Unselect row
tableView.deselectRow(at: indexPath, animated: false)
// Toggle selectionlet item = self.items[indexPath.row]
item.selected = !item.selected
tableView.reloadData()
}
Однако радиокнопки требуют специальной реализации, см. Другие ответы.
Решение о том, поставить или снять отметку с кнопки флажка, выходит за рамки представления. Само представление должно заботиться только о рисовании элементов, а не о их внутреннем состоянии. Моя предлагаемая реализация выглядит следующим образом:
Его можно использовать с 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)
}
У меня недостаточно репутации, чтобы давать комментарии, поэтому я оставлю здесь свою версию версии Салила Двахана . Работает для Swift 5, XCode 11.3.
Сначала поместите свою кнопку на IB, выберите тип «Custom» и создайте выход и действие с помощью макета помощника ( Ctrl+ перетаскивание). Включите следующий код, и он должен заканчиваться так:
Хотя в некоторых ответах правильно упоминается, что мы можем использовать Selected State для установки изображения для выбранного состояния кнопки, это не будет работать элегантно, когда кнопка должна иметь и изображение, и текст.
Как и многие, я закончил тем, что создал подкласс UIButton; однако добавлена поддержка установки изображений из Интерфейсного разработчика.
Ответы:
Для радиокнопок и флажков нет ничего встроенного.
Вы можете легко реализовать флажки самостоятельно. Вы можете установить uncheckedImage для своей кнопки для UIControlStateNormal и checkedImage для своего UIControlStateSelected. Теперь при нажатии кнопка изменит свое изображение и будет переключаться между отмеченным и непроверенным изображением.
Чтобы использовать радиокнопки, вы должны оставить
Array
для всех кнопок, которые вы хотите использовать как радиокнопки. Каждый раз, когда нажимается кнопка, вам необходимо снять отметку со всех других кнопок в массиве.Для переключателей вы можете использовать SSRadioButtonsController. Вы можете создать объект контроллера и добавить к нему массив кнопок, например
var radioButtonController = SSRadioButtonsController() radioButtonController.setButtonsArray([button1!,button2!,button3!])
Главный принцип здесь примерно такой .
источник
Флажок
Вы можете создать свой собственный элемент управления 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!] }
Надеюсь, поможет.
источник
Проверьте DLRadioButton . Вы можете добавлять и настраивать переключатели непосредственно из Интерфейсного разработчика. Также
Swift
отлично работает с .Обновление: в версии
1.3.2
добавлены квадратные кнопки, также улучшена производительность.Обновление: в версии
1.4.4
добавлена опция множественного выбора, также может использоваться как флажок.Обновление: в версию
1.4.7
добавлена поддержка языка RTL.источник
multipleSelectionEnabled
иiconSquare
наYES
.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
источник
didSet
checkBoxOutlet.layer.cornerRadius = checkBoxOutlet.frame.height / 2
И чтобы удалить синий цвет,tint
когда кнопка выбрана, вы можете добавить эту строку в расширениеself.adjustsImageWhenHighlighted = false self.isHighlighted = false
Есть действительно отличная библиотека, которую вы можете использовать для этого (вы действительно можете использовать ее вместо
UISwitch
): https://github.com/Boris-Em/BEMCheckBoxНастройка проста:
BEMCheckBox *myCheckBox = [[BEMCheckBox alloc] initWithFrame:CGRectMake(0, 0, 50, 50)]; [self.view addSubview:myCheckBox];
Предусмотрены флажки круглого и квадратного типа.
А еще делает анимацию:
источник
Очень простой элемент управления флажком.
@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; } }
источник
короче версия 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 }
источник
Решение для 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.
Результат:
источник
RadioButtonController
экземпляра я использовал проверку тега,selectedButton
чтобы отличить то, что было выбрано. Спасибо чувак!Шаги по созданию радиокнопки
BasicStep: возьмите две кнопки. установить изображение как для выбранного, так и для невыделенного. чем добавить действие к обеим кнопкам. теперь начните код
1) Создайте переменную:
var btnTag : Int = 0
2) В ViewDidLoad определите:
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 } }
Радиокнопка готова для вас
источник
Для флажка не нужно создавать подкласс 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 }
источник
Вы можете просто создать подкласс 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() } } }
источник
Я сделал супер простой класс для решения этой проблемы в приложении 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 } }
источник
@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) }
источник
Для флажков есть встроенное решение в виде аксессуаров 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() }
Однако радиокнопки требуют специальной реализации, см. Другие ответы.
источник
Решение о том, поставить или снять отметку с кнопки флажка, выходит за рамки представления. Само представление должно заботиться только о рисовании элементов, а не о их внутреннем состоянии. Моя предлагаемая реализация выглядит следующим образом:
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) }
источник
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) } }
источник
У меня недостаточно репутации, чтобы давать комментарии, поэтому я оставлю здесь свою версию версии Салила Двахана . Работает для 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
это способ проверитьисточник
Хотя в некоторых ответах правильно упоминается, что мы можем использовать 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 } } }
источник