설문 조사를 할 수있는 앱을 개발 중입니다. 내 레이아웃은 XML 기반 질문에서 생성됩니다.
라디오 버튼 (단일 선택)과 확인란 (복수 답변)을 만들어야합니다. 나는 신속하게 유용한 것을 찾지 못했습니다.
누구 아이디어가 있습니까?
설문 조사를 할 수있는 앱을 개발 중입니다. 내 레이아웃은 XML 기반 질문에서 생성됩니다.
라디오 버튼 (단일 선택)과 확인란 (복수 답변)을 만들어야합니다. 나는 신속하게 유용한 것을 찾지 못했습니다.
누구 아이디어가 있습니까?
답변:
라디오 버튼 및 체크 박스의 경우 기본 제공되는 항목이 없습니다.
체크 박스를 쉽게 구현할 수 있습니다. UIControlStateNormal에 대해서는 버튼에 uncheckedImage를, UIControlStateSelected에 대해서는 checkedImage를 설정할 수 있습니다. 이제 탭하면 버튼이 이미지를 변경하고 확인 된 이미지와 선택되지 않은 이미지를 번갈아 표시합니다.
라디오 버튼을 사용하려면 라디오 버튼 Array
으로 작동 할 모든 버튼에 대해 를 유지해야 합니다. 버튼을 누를 때마다 어레이의 다른 모든 버튼을 선택 취소해야합니다.
라디오 버튼의 경우 SSRadioButtonsController 를 사용할 수 있습니다. 컨트롤러 객체를 만들고 다음과 같이 버튼 배열을 추가 할 수 있습니다.
var radioButtonController = SSRadioButtonsController()
radioButtonController.setButtonsArray([button1!,button2!,button3!])
주요 원칙은 여기에 있습니다 .
체크 박스
Swift로 UIButton을 확장하는 고유 한 CheckBox 컨트롤을 만들 수 있습니다.
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을 확인하십시오 . Interface Builder에서 직접 라디오 버튼을 추가하고 사용자 정의 할 수 있습니다. 또한 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
}
타사 라이브러리를 사용하지 않고 Swift 4.2의 Radio Button 솔루션
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)
}
}
Assets에 radio_off 및 radio_on 이미지를 추가해야합니다.
결과:
RadioButtonController
예, 나는의 태그 체크 아웃 사용 selectedButton
선택되어 있는지 구별 할 수 있습니다. 감사합니다!
라디오 버튼을 만드는 단계
BasicStep : Two Button을 선택합니다. 선택한 것과 선택되지 않은 것과 같은 이미지를 설정하십시오. 두 버튼에 액션을 추가하는 것보다. 이제 시작 코드
1) 변수 생성 :
var btnTag : Int = 0
2) ViewDidLoad에서 정의 :
btnTag = btnSelected.tag
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
}
작업중인 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
}
}
}
}
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
}
}
UIButton을 하위 클래스로 만들고 필요에 맞게 자체 그리기 코드를 작성할 수 있습니다. 다음 코드를 사용하여 Android와 같은 라디오 버튼을 구현했습니다. 스토리 보드에서도 사용할 수 있습니다. 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()
}
}
}
@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 액세서리 형태의 기본 제공 솔루션 이 있습니다. 각 셀을 선택 가능한 옵션으로 사용 accessoryType
하고 선택한 항목에 대한 확인 표시를 설정하는 데 사용하는 UITableView로 양식을 설정할 수 있습니다 .
다음은 의사 코드 예입니다.
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 업데이트 된 Swift 용 Simple RadioButton (라이브러리 없음)
먼저 이미지를 One Checked 및 Second Unchecked 버튼으로 설정합니다.
그런 다음 RadioButton의 2 개의 콘센트를 제공합니다.
@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)
}
}
댓글을 달만한 평판이 충분하지 않으므로 여기 에 Salil Dwahan 버전을 남겨 두겠습니다 . Swift 5, XCode 11.3에서 작동합니다.
먼저 IB에 버튼을 놓고 "사용자 지정"유형을 선택한 다음 어시스턴트 레이아웃 ( 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)
}
}
자산에 이미지를 추가하고 일치하도록 이름을 변경하는 것을 잊지 마십시오!
checkbox.isSelected
확인하는 방법입니다
일부 답변은 Selected State를 사용하여 버튼의 Selected 상태에 대한 이미지를 설정할 수 있다고 올바르게 언급하지만 버튼에 이미지와 텍스트가 모두 있어야 할 때는 우아하게 작동하지 않습니다.
많은 사람들과 마찬가지로 UIButton을 서브 클래 싱하여 끝냈습니다. 그러나 Interface Builder에서 이미지 설정에 대한 지원이 추가되었습니다.
아래는 내 코드입니다.
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
}
}
}