Подтвердить что ты не робот

Как создать переключатели и флажок в swift (iOS)?

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Основной принцип - это что-то вроде здесь.

Ответ 2

флажок

Вы можете создать свой собственный элемент управления 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: UIControlState.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:

enter image description here

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

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

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

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

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

    override func awakeFromNib() {
        self.view.layoutIfNeeded()

        womanRadioButton.selected = true
        manRadioButton.selected = false
    }

    override func viewDidLoad() {
        womanRadioButton?.alternateButton = [manRadioButton!]
        manRadioButton?.alternateButton = [womanRadioButton!]
    }

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

Ответ 3

Отъезд DLRadioButton. Вы можете добавлять и настраивать радиокнопки непосредственно из Interface Builder. Также отлично работает с Swift.

Swift Radio Button для iOS

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

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

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

Ответ 4

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

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

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

Он обеспечивает круглые и квадратные флажки

enter image description here

А также анимации:

enter image description here

Ответ 5

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

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

Ответ 6

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

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

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

var btnTag    : Int = 0

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

 btnTag = btnSelected.tag

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

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

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

Ответ 7

короткая версия 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
    }

Ответ 8

Для флажка вам не нужно подклассифицировать 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
}

Ответ 9

  1. Создайте 2 кнопки, одну как "ДА", а другую как "НЕТ".
  2. Создайте свойство BOOL, например: isNRICitizen = false
  3. Соедините обе кнопки одинаково и установите метку (например, кнопка "Да" - метка 10 и кнопка "Нет" -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)
}

Ответ 10

Для флажков на самом деле есть встроенное решение в виде аксессуаров 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()
    }

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

Ответ 11

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

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

Может использоваться с Интерфейсным Разработчиком или программно. Использование представления может быть в качестве следующего примера:

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

Ответ 12

Мне доставляет большое удовольствие сообщить вам все, что решают вышеуказанную проблему.

Решение проблемы

  1. Функциональность CheckBox
  2. Функциональность RadioButton
  3. ReuseCell (tableView.dequeueReusableCell)//Также решаем проблему выбранной позиции ячейки.

Протестированный код

  • Swift 5
  • iOS 12.2

Вот мой код

import UIKit

class countrySelection:UITableViewCell{
     @IBOutlet weak var imgFlag: UIImageView!
     @IBOutlet weak var lblCountryName: UILabel!
     @IBOutlet weak var btnSelection: UIButton!
}

class ViewController: UIViewController {

    var listingDict=[[String:String]]()

    var radioOption:Int?// Only used :: if u are 2. RadioButton Functionality impliment

    @IBOutlet weak var tableView: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.dataSource=self
        tableView.delegate=self

        fillCountryData()
        // Do any additional setup after loading the view.
    }

    func fillCountryData(){
        self.fillJsonData(imgName: "india_flag", countryName: "India")
        self.fillJsonData(imgName: "pakistan_flag", countryName: "Pakistan")
        self.fillJsonData(imgName: "israel_flag", countryName: "Israel")
        self.fillJsonData(imgName: "albania_flag", countryName: "Albania")
        self.fillJsonData(imgName: "america_flag", countryName: "America")
        self.fillJsonData(imgName: "belize_flag", countryName: "Belize")
        self.fillJsonData(imgName: "brunei_flag", countryName: "Brunei")
        self.fillJsonData(imgName: "comoros_flag", countryName: "Comoros")
        self.fillJsonData(imgName: "congo_flag", countryName: "Congo")
        self.fillJsonData(imgName: "ecuador_flag", countryName: "Ecuador")
        self.fillJsonData(imgName: "haiti_flag", countryName: "Haiti")
        self.fillJsonData(imgName: "jamaica_flag", countryName: "Jamaica")
        self.fillJsonData(imgName: "kenya_flag", countryName: "Kenya")
        self.fillJsonData(imgName: "mali_flag", countryName: "Mali")

        self.tableView.reloadData()
    }

    func fillJsonData(imgName:String,countryName:String){
        var dictData=[String:String]()
        dictData["img"]=imgName
        dictData["country"]=countryName
        dictData["check"]="false"
        listingDict.append(dictData)
    }

}

extension ViewController:UITableViewDataSource,UITableViewDelegate{

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return listingDict.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell=tableView.dequeueReusableCell(withIdentifier: "countrySelection") as! countrySelection
        let dictVal=listingDict[indexPath.row]
        cell.lblCountryName.text=dictVal["country"]
        cell.imgFlag.image=UIImage(named:dictVal["img"]!)

        /*//Check Box Functionality
        if dictVal["check"] == "false"{
            cell.btnSelection.setImage(UIImage(named: "checkbox_UnSelect"), for: .normal)
        } else{
            cell.btnSelection.setImage(UIImage(named: "checkbox_Select"), for: .normal)
        }*/

        //RadioButton Functionality
        if radioOption==indexPath.row{
            listingDict[indexPath.row]["check"]="true"
            cell.btnSelection.setImage(UIImage(named: "radioButton_Select"), for: .normal)
        } else{
            listingDict[indexPath.row]["check"]="false"
            cell.btnSelection.setImage(UIImage(named: "radioButton_UnSelect"), for: .normal)
        }

        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        /*//CheckBox Functionality
        if listingDict[indexPath.row]["check"]=="true"{
            listingDict[indexPath.row]["check"]="false"
        } else{
            listingDict[indexPath.row]["check"]="true"
        }*/
        //RadioButton Functionality
        print("RadioButton",listingDict)
        if listingDict[indexPath.row]["check"]=="true"{
            radioOption=nil
        } else{
            radioOption=indexPath.row
        }

        self.tableView.reloadData()
    }
}

Ответ 13

Вы можете просто подклассифицировать UIButton и написать свой собственный код чертежа в соответствии с вашими потребностями. Я применил радиокнопку, подобную андроиду, используя следующий код. Его также можно использовать в раскадровке. См. Пример в репозитории 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()
    }
}
}