Anket yapmaya izin veren bir uygulama geliştiriyorum. Düzenim XML tabanlı sorulardan oluşturuldu.
Radyo düğmeleri (tek seçenek) ve onay kutuları (birden çok yanıt) oluşturmam gerekiyor. Hızlı için yararlı bir şey bulamadım.
Bir fikri olan var mı?
Anket yapmaya izin veren bir uygulama geliştiriyorum. Düzenim XML tabanlı sorulardan oluşturuldu.
Radyo düğmeleri (tek seçenek) ve onay kutuları (birden çok yanıt) oluşturmam gerekiyor. Hızlı için yararlı bir şey bulamadım.
Bir fikri olan var mı?
Yanıtlar:
Radyo Düğmeleri ve Onay Kutuları için yerleşik olarak gelen hiçbir şey yoktur.
Onay Kutularını kendiniz kolayca uygulayabilirsiniz. UIControlStateNormal için düğmeniz için bir uncheckedImage ve UIControlStateSelected için bir checkedImage ayarlayabilirsiniz. Şimdi dokunduğunuzda, düğme görüntüsünü değiştirecek ve işaretli ve kontrol edilmemiş görüntü arasında geçiş yapacaktır.
Radyo düğmelerini kullanmak Array
için, radyo düğmeleri olarak davranmasını istediğiniz tüm düğmeler için bir tutmanız gerekir . Bir düğmeye her basıldığında, dizideki diğer tüm düğmelerin işaretini kaldırmanız gerekir.
Radyo düğmeleri için SSRadioButtonsController'ı kullanabilirsiniz Bir denetleyici nesnesi oluşturabilir ve buna düğmeler dizisi ekleyebilirsiniz.
var radioButtonController = SSRadioButtonsController()
radioButtonController.setButtonsArray([button1!,button2!,button3!])
Ana prensip burada bunun gibi bir şey .
Onay kutusu
Swift ile UIButton'u genişleten kendi CheckBox kontrolünüzü oluşturabilirsiniz:
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
}
}
}
Ardından, Interface Builder ile görünümlerinize ekleyin:
Radyo Düğmeleri
Radyo Düğmeleri de benzer şekilde çözülebilir.
Örneğin, Kadın - Erkek klasik cinsiyet seçimi :
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
}
}
}
}
Radyo düğmelerinizi şu şekilde başlatabilirsiniz:
override func awakeFromNib() {
self.view.layoutIfNeeded()
womanRadioButton.selected = true
manRadioButton.selected = false
}
override func viewDidLoad() {
womanRadioButton?.alternateButton = [manRadioButton!]
manRadioButton?.alternateButton = [womanRadioButton!]
}
Umarım yardımcı olur.
DLRadioButton'a göz atın . Radyo düğmelerini doğrudan Arayüz Oluşturucu'dan ekleyebilir ve özelleştirebilirsiniz. Ayrıca Swift
mükemmel bir şekilde çalışır .
Güncelleme: sürüm 1.3.2
kare düğmeler ekledi, ayrıca performansı artırdı.
Güncelleme: sürüm 1.4.4
çoklu seçim seçeneği ekledi, onay kutusu olarak da kullanılabilir.
Güncelleme: sürüm 1.4.7
, RTL dil desteği ekledi.
multipleSelectionEnabled
ve iconSquare
için YES
.
Swift 5, Animasyonlu Onay Kutusu
Düğmenin bir çıkışını oluşturun
@IBOutlet weak var checkBoxOutlet:UIButton!{
didSet{
checkBoxOutlet.setImage(UIImage(named:"unchecked"), for: .normal)
checkBoxOutlet.setImage(UIImage(named:"checked"), for: .selected)
}
}
Bir UIButton uzantısı oluşturun
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)
}
}
}
Nasıl kullanılır
@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)
}
}
Onay Kutusu ve Radyo düğmesi için Örneğimi kontrol edin https://github.com/rashidlatif55/CheckBoxAndRadioButton
didSet
checkBoxOutlet.layer.cornerRadius = checkBoxOutlet.frame.height / 2
Ve tint
buton seçildiğinde maviyi kaldırmak için bu satırı uzantıya ekleyebilirsiniz self.adjustsImageWhenHighlighted = false self.isHighlighted = false
Bunun için kullanabileceğiniz gerçekten harika bir kitaplık var (bunun yerine bunu kullanabilirsiniz UISwitch
): https://github.com/Boris-Em/BEMCheckBox
Kurulum kolaydır:
BEMCheckBox *myCheckBox = [[BEMCheckBox alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
[self.view addSubview:myCheckBox];
Daire ve kare tip onay kutuları sağlar
Ayrıca animasyonlar da yapıyor:
Çok basit bir onay kutusu kontrolü.
@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;
}
}
daha kısa ios swift 4 sürümü:
@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
}
Üçüncü taraf kitaplıkları kullanmadan Swift 4.2'deki Radyo Düğmesi için Çözüm
RadioButtonController.swift dosyası oluşturun ve aşağıdaki kodu içine yerleştirin:
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
}
}
}
}
Görünüm denetleyici dosyanızda aşağıdaki gibi kullanın:
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)
}
}
Varlıklar'a radio_off ve radio_on görüntülerini eklediğinizden emin olun.
Sonuç:
RadioButtonController
Mesela, ben etiketini kontrol kullanılan selectedButton
seçilmiştir ne ayırt etmek. Teşekkürler dostum!
Radyo Düğmesi Oluşturma Adımları
BasicStep: İki Düğme alın. hem seçilmiş hem de seçilmemiş gibi görüntüyü ayarlayın. her iki düğmeye de eylem eklemek yerine. şimdi kodu başlat
1) Değişken oluşturun:
var btnTag : Int = 0
2) ViewDidLoad Define içinde:
btnTag = btnSelected.tag
3) Şimdi Seçilen Dokunma İşleminde:
@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 Düğmesi için kod yapın
@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
}
}
Radyo Düğmesi sizin için Hazır
Bir onay kutusu için, UIButton'u alt sınıflara ayırmanıza gerek yoktur. Bunu isSelected
halletme özelliğine zaten sahip .
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)
Sonra eylem yönteminde isSelected
durumunu değiştirin.
@objc func toggleCheckboxSelection() {
checkbox.isSelected = !checkbox.isSelected
}
UIButton'ı alt sınıflara ayırabilir ve ihtiyaçlarınıza uyacak şekilde kendi çizim kodunuzu yazabilirsiniz. Aşağıdaki kodu kullanarak android'inki gibi bir radyo düğmesi uyguladım. Film şeridinde de kullanılabilir. Github deposundaki örneğe bakın
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()
}
}
}
Üzerinde çalıştığım bir Mac uygulamasında bunu halletmek için süper basit bir ders yaptım. Umarım bu birisi için yararlıdır
RadioButtonController Sınıfı:
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
}
}
}
}
View Controller'da Uygulama:
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)
}
Onay kutuları için aslında UITableViewCell aksesuarları biçiminde yerleşik bir çözüm vardır. Formunuzu, her hücrenin seçilebilir bir seçenek olarak gördüğü ve accessoryType
seçilen öğeler için bir onay işareti koymak için kullanıldığı bir UITableView olarak kurabilirsiniz .
İşte sözde kod örneği:
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()
}
Ancak radyo düğmeleri özel bir uygulama gerektirir, diğer yanıtlara bakın.
Onay kutusu düğmesinin işaretlenmesi veya işaretinin kaldırılması kararı, görünümün kapsamı dışında kalan bir şeydir. Görünümün kendisi sadece unsurları çizmeye özen göstermeli, iç durumu hakkında karar vermemelidir. Benim önerdiğim uygulama şu şekildedir:
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 ile veya programlı olarak kullanılabilir. Görünümün kullanımı aşağıdaki örnek gibi olabilir:
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, Swift İçin Güncellenmiş Basit RadioButton (Kitaplık Yok)
Önce görüntüleri Bir Kontrol Edildi ve İkinci Kontrol Edilmedi düğmesine ayarlayın.
Ardından RadioButton'un 2 Çıkışını Sağlayın.
@IBOutlet weak var radioMale: UIButton!
@IBOutlet weak var radioFemale: UIButton!
Tek Yöntemde Her İki Düğme Eylemiyle IBAction Oluşturun.
@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)
}
}
Yorum yapacak kadar itibarım yok, bu yüzden Salil Dwahan versiyonumu bırakacağım versiyonunu burada . Swift 5, XCode 11.3 için çalışır.
Öncelikle düğmenizi IB'ye yerleştirin, "Özel" türünü seçin ve Asistan Düzeni ile bir çıkış ve bir eylem oluşturun ( Ctrl+ Sürükle). Aşağıdaki kodu ekleyin ve bu şekilde bitmelidir:
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)
}
}
Görüntüyü Varlıklar'a eklemeyi ve eşleşecek şekilde adı değiştirmeyi unutmayın!
checkbox.isSelected
kontrol etmenin yolu
Bazı yanıtlar, düğmenin Seçili durumu için bir görüntü ayarlamak için Seçili Durum'u kullanabileceğimizi doğru bir şekilde belirtmesine rağmen, düğmenin hem görüntü hem de metne sahip olması gerektiğinde, şık bir şekilde çalışmayacaktır.
Birçok kişi gibi ben de UIButton'u alt sınıflara ayırarak bitirdim; ancak, Interface Builder'dan görüntülerin ayarlanması için destek eklendi.
Kodum aşağıdadır:
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
}
}
}