Ich entwickle eine App, mit der Umfragen durchgeführt werden können. Mein Layout wird aus XML-basierten Fragen generiert.
Ich muss Optionsfelder (einfache Auswahl) und Kontrollkästchen (mehrere Antworten) erstellen. Ich fand nichts Nützliches für schnell.
Hat jemand eine Idee?
Antworten:
Für Optionsfelder und Kontrollkästchen ist nichts eingebaut.
Sie können Checkboxes einfach selbst implementieren. Sie können ein ungeprüftes Bild für Ihre Schaltfläche für UIControlStateNormal und ein geprüftes Bild für Ihr UIControlStateSelected festlegen. Wenn Sie jetzt auf tippen, ändert die Schaltfläche ihr Bild und wechselt zwischen aktiviertem und nicht aktiviertem Bild.
Um Optionsfelder verwenden zu können, müssen Sie
Array
für alle Schaltflächen, die Sie als Optionsfelder verwenden möchten, ein anhalten. Immer wenn eine Taste gedrückt wird, müssen Sie alle anderen Tasten im Array deaktivieren.Für Optionsfelder können Sie SSRadioButtonsController verwenden. Sie können ein Controller-Objekt erstellen und wie folgt ein Array mit Schaltflächen hinzufügen
var radioButtonController = SSRadioButtonsController() radioButtonController.setButtonsArray([button1!,button2!,button3!])
Das Prinzip ist so etwas wie hier diese .
quelle
Kontrollkästchen
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: 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 } } }
Fügen Sie es dann mit Interface Builder zu Ihren Ansichten hinzu:
Radio Knöpfe
Optionsfelder können auf ähnliche Weise gelöst werden.
Zum Beispiel die klassische Geschlechtsauswahl Frau - Mann :
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 folgendermaßen aktivieren:
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.
quelle
Schauen Sie sich DLRadioButton an . Sie können Optionsfelder direkt im Interface Builder hinzufügen und anpassen. Funktioniert auch
Swift
perfekt mit.Update: Version
1.3.2
mit quadratischen Schaltflächen hinzugefügt, außerdem verbesserte Leistung.Update: Version
1.4.4
mit Mehrfachauswahloption hinzugefügt, kann auch als Kontrollkästchen verwendet werden.Update: Version
1.4.7
hinzugefügt RTL-Sprachunterstützung.quelle
multipleSelectionEnabled
undiconSquare
zuYES
.Swift 5, Kontrollkästchen mit Animation
Erstellen Sie einen Ausgang der Schaltfläche
@IBOutlet weak var checkBoxOutlet:UIButton!{ didSet{ checkBoxOutlet.setImage(UIImage(named:"unchecked"), for: .normal) checkBoxOutlet.setImage(UIImage(named:"checked"), for: .selected) } }
Erstellen Sie eine Erweiterung von 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) } } }
Wie benutzt man
@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) } }
Überprüfen Sie mein Beispiel für Kontrollkästchen und Optionsfeld https://github.com/rashidlatif55/CheckBoxAndRadioButton
quelle
didSet
checkBoxOutlet.layer.cornerRadius = checkBoxOutlet.frame.height / 2
Und um das Blau zu entfernen,tint
wenn die Schaltfläche ausgewählt ist, können Sie diese Zeile in der Erweiterung hinzufügenself.adjustsImageWhenHighlighted = false self.isHighlighted = false
Es gibt eine wirklich großartige Bibliothek, die Sie dafür verwenden können (Sie können diese tatsächlich anstelle von verwenden
UISwitch
): https://github.com/Boris-Em/BEMCheckBoxDie Einrichtung ist einfach:
BEMCheckBox *myCheckBox = [[BEMCheckBox alloc] initWithFrame:CGRectMake(0, 0, 50, 50)]; [self.view addSubview:myCheckBox];
Es bietet Kontrollkästchen für Kreistypen und Quadrate
Und es macht auch Animationen:
quelle
Eine sehr einfache Checkbox-Steuerung.
@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; } }
quelle
kürzere 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 }
quelle
Lösung für Optionsfelder in Swift 4.2 ohne Verwendung von Bibliotheken von Drittanbietern
Erstellen Sie die Datei RadioButtonController.swift und fügen Sie den folgenden Code ein:
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 } } } }
Verwenden Sie es wie folgt in Ihrer View Controller-Datei:
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) } }
Stellen Sie sicher, dass Sie in Assets die Bilder radio_off und radio_on hinzufügen.
Ergebnis:
quelle
RadioButtonController
Instanz habe ich das Tag von ausgecheckt, umselectedButton
zu unterscheiden, was ausgewählt wurde. Danke, Mann!Schritte zum Erstellen eines Optionsfelds
BasicStep: Nimm zwei Tasten. Stellen Sie das Bild sowohl für ausgewählt als auch für nicht ausgewählt ein. als Aktion zu beiden Schaltfläche hinzufügen. Starten Sie jetzt den Code
1) Variable erstellen:
var btnTag : Int = 0
2) In ViewDidLoad Definieren Sie:
3) Jetzt in ausgewählter Tippaktion:
@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 ausführen
@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 } }
Das Optionsfeld ist bereit für Sie
quelle
Für ein Kontrollkästchen müssen Sie den UIButton nicht unterordnen. Es hat bereits die
isSelected
Eigenschaft, dies zu handhaben.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)
Schalten Sie dann in der Aktionsmethode den
isSelected
Status um.@objc func toggleCheckboxSelection() { checkbox.isSelected = !checkbox.isSelected }
quelle
Ich habe eine supereinfache Klasse erstellt, um dies in einer Mac-Anwendung zu handhaben, an der ich arbeite. Hoffentlich ist dies für jemanden hilfreich
RadioButtonController Klasse:
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 } } }
}}
Implementierung 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 } }
quelle
Sie können einfach UIButton unterordnen und Ihren eigenen Zeichnungscode schreiben, der Ihren Anforderungen entspricht. 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() } } }
quelle
@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) }
quelle
Für Kontrollkästchen gibt es tatsächlich 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 und Verwendung verwendet wird
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.
quelle
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 über den internen Zustand entscheiden. 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 sein:
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) }
quelle
Swift 5.0 Aktualisierter einfacher RadioButton für Swift (keine Bibliothek)
Stellen Sie zuerst die Bilder auf die Schaltfläche Eins aktiviert und Zweit deaktiviert.
Stellen Sie dann 2 Outlet Of RadioButton bereit.
@IBOutlet weak var radioMale: UIButton! @IBOutlet weak var radioFemale: UIButton!
Erstellen Sie eine IBAction mit beiden Schaltflächenaktionen in einer Methode.
@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) } }
quelle
Ich habe nicht genug Ruf, um einen Kommentar abzugeben , deshalb werde ich meine Version von Salil Dwahan verlassen Version hier lassen. Funktioniert für Swift 5, XCode 11.3.
Platzieren Sie zuerst Ihre Schaltfläche auf IB, wählen Sie "Benutzerdefiniert" und erstellen Sie eine Steckdose und eine Aktion mit dem Assistentenlayout ( Ctrl+ Ziehen). Fügen Sie den folgenden Code ein und er sollte folgendermaßen enden:
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) } }
Vergessen Sie nicht, das Bild zu Assets hinzuzufügen und den Namen entsprechend zu ändern!
checkbox.isSelected
ist der Weg zu überprüfenquelle
Obwohl einige der Antworten zu Recht erwähnen, dass wir den ausgewählten Status verwenden können, um ein Bild für den ausgewählten Status der Schaltfläche festzulegen, funktioniert es nicht elegant, wenn die Schaltfläche sowohl Bild als auch Text enthalten muss.
Wie viele andere endete ich mit der Unterklasse von UIButton. Unterstützung für das Festlegen von Bildern in Interface Builder wurde jedoch hinzugefügt.
Unten ist mein 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 } } }
quelle