wake-up-neo.com

Wie erstelle ich Optionsfelder und Kontrollkästchen in Swift (iOS)?

Ich entwickle eine App, die eine Umfrage ermöglicht. Mein Layout wird aus XML-basierten Fragen generiert. 

Ich muss Optionsfelder (einfache Auswahl) und Kontrollkästchen (mehrere Antworten) erstellen. Ich habe nichts Nützliches für Swift gefunden. 

Hat jemand eine Idee?

53
Vannian

Für Radio Buttons und CheckBoxes ist nichts eingebaut. 

Sie können Checkboxen einfach selbst implementieren. Sie können für UIControlStateNormal ein uncheckedImage und für UIControlStateSelected ein checkedImage festlegen. Wenn Sie jetzt auf die Schaltfläche tippen, ändert sich die Schaltfläche und wechselt zwischen aktiviertem und ungeprüftem Bild. 

Um Optionsfelder verwenden zu können, müssen Sie eine Array für alle Tasten behalten, die Sie als Optionsfelder verwenden möchten. Immer wenn eine Taste gedrückt wird, müssen Sie alle anderen Tasten im Array deaktivieren. 

Für Radiobuttons können Sie SSRadioButtonsController .__ verwenden. Sie können ein Controller-Objekt erstellen und Schaltflächen-Array hinzufügen 

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

Das Hauptprinzip ist so etwas wie dies hier .

34
S Shahid

Checkbox

Sie können mit Swift ein eigenes CheckBox-Steuerelement erstellen, das UIButton erweitert:

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: UIControlState.normal)
            } else {
                self.setImage(uncheckedImage, for: UIControlState.normal)
            }
        }
    }

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

    func buttonClicked(sender: UIButton) {
        if sender == self {
            isChecked = !isChecked
        }
    }
}

Und fügen Sie es dann mit Interface Builder zu Ihren Ansichten hinzu:

 enter image description here

Radio Knöpfe

Optionsfelder können auf ähnliche Weise gelöst werden.

Zum Beispiel die klassische Geschlechtsauswahl Frau - Mann:

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

Sie können Ihre Optionsfelder wie folgt auslösen:

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

        womanRadioButton.selected = true
        manRadioButton.selected = false
    }

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

Ich hoffe es hilft.

111
crubio

Check out DLRadioButton . Sie können Optionsfelder direkt aus dem Interface Builder hinzufügen und anpassen. Funktioniert auch perfekt mit Swift.

 Swift Radio Button for iOS

Update: Version 1.3.2 fügte quadratische Schaltflächen hinzu und verbesserte die Leistung.

Update: Version 1.4.4 hinzugefügte Mehrfachauswahloption, kann auch als Kontrollkästchen verwendet werden.

Update: Version 1.4.7 hat Unterstützung für RTL-Sprachen hinzugefügt.

21
David Liu

Es gibt eine wirklich großartige Bibliothek, die Sie dafür verwenden können (Sie können diese anstelle von UISwitch verwenden): https://github.com/Boris-Em/BEMCheckBox

Das Setup ist einfach:

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

Sie enthält Kontrollkästchen für den Typ Kreis und Quadrat 

 enter image description here

Und es gibt auch Animationen:

 enter image description here

8
Calvin Alvin

Ein sehr einfaches Kontrollkästchen.

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

Schritte zum Erstellen eines Optionsfelds

BasicStep: Take Two Button. Legen Sie das Bild für den ausgewählten und den nicht ausgewählten Bereich fest

1) Variable erstellen: 

var btnTag    : Int = 0

2) In ViewDidLoad definieren: 

 btnTag = btnSelected.tag

3) Jetzt in der ausgewählten Tap-Aktion:

 @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) Code für UnCheck Button eingeben

 @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 ist für Sie bereit

2
Krutarth Patel

kürzere Version von 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
    }
2
Gulz

Für ein Kontrollkästchen müssen Sie den UIButton nicht subklassifizieren. Es verfügt bereits über die isSelected-Eigenschaft, um damit umzugehen.

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)

In der Aktionsmethode Toggle ist dann der Status isSelected.

@objc func toggleCheckboxSelection() {
    checkbox.isSelected = !checkbox.isSelected
}
1
Salil Dhawan
  1. Erstellen Sie 2 Knöpfe als "JA" und einen weiteren als "NEIN".
  2. Erstellen Sie eine BOOL-Eigenschaft Ex: isNRICitizen = false
  3. Geben Sie den beiden Schaltflächen dieselbe Schaltflächenverbindung, und legen Sie ein Tag fest
@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
Ravindra Kishan

Die Entscheidung, das Kontrollkästchen zu aktivieren oder zu deaktivieren, liegt außerhalb des Bereichs der Ansicht. View selbst sollte sich nur um das Zeichnen der Elemente kümmern und nicht um deren internen Zustand. Meine vorgeschlagene Implementierung lautet wie folgt:

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

Es kann mit Interface Builder oder programmgesteuert verwendet werden. Die Verwendung der Ansicht könnte wie folgt aussehen:

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

Für Checkboxen gibt es eigentlich eine integrierte Lösung in Form von UITableViewCell-Zubehör. Sie können Ihr Formular als UITableView einrichten, in dem jede Zelle als auswählbare Option verwendet wird, und mit accessoryType ein Häkchen für ausgewählte Elemente setzen.

Hier ist ein Pseudocode-Beispiel:

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

Optionsfelder erfordern jedoch eine benutzerdefinierte Implementierung, siehe die anderen Antworten.

0
Aron

Sie können UIButton einfach in Unterklassen unterteilen und Ihren eigenen Zeichnungscode gemäß Ihren Anforderungen schreiben. Ich habe ein Optionsfeld wie das von Android mit dem folgenden Code implementiert. Es kann auch im Storyboard verwendet werden. Siehe Beispiel 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()
    }
}
}
0
Nikesh Jha