如何在swift中动态创建单选按钮?

时间:2016-08-03 15:14:19

标签: ios swift radio-button

我有以下按钮,根据某些条件动态添加。现在我需要将所有添加的按钮行为更改为单选按钮。这样我就可以根据选择做一些动作。

  var posX = 0
    var posY = 0

    if trim.contains("0"){
        print("contaim 0")
        let button1 = UIButton(frame: CGRect(x: posX, y: posY, width: 60, height: 20))
        button1.setTitleColor(UIColor.blackColor(), forState: .Normal)
        button1.setTitle("No", forState: .Normal)
        button1.setImage(UIImage(named: "checkbox untick.png")!, forState: .Normal)
        button1.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside)
        myStackview.addSubview(button1)
        posX = 60
    }
    if trim.contains("1") {
        print("contaim 1")

        let button2 = UIButton(frame: CGRect(x: posX, y: posY, width: 60, height: 20))
            button2.setTitleColor(UIColor.blackColor(), forState: .Normal)
            button2.setTitle("Less", forState: .Normal)
            button2.setImage(UIImage(named: "checkbox untick.png")!, forState: .Normal)
            button2.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside)
            myStackview.addSubview(button2)
            posX = posX + 60

    }
    if trim.contains("2"){
        print("contaim 2")

        let button3 = UIButton(frame: CGRect(x: posX, y: posY, width: 60, height: 20))
        button3.setTitleColor(UIColor.blackColor(), forState: .Normal)

        button3.setTitle("Half", forState: .Normal)
        button3.setImage(UIImage(named: "checkbox untick.png")!, forState: .Normal)
        button3.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside)
        myStackview.addSubview(button3)
        posX =  posX + 60
    }

我已将buttonAction方法设置如下,但它不起作用

func buttonAction(sender: UIButton!) {
    print("Button tapped")
    sender.setImage(UIImage(named: "checkboxredtick.png")!, forState: .Normal)

}

3 个答案:

答案 0 :(得分:5)

let buttons = [UIButton]()
// create button1
let button1 = UIButton(frame: CGRect(x: posX, y: posY, width: 60, height: 20))
button1.setTitleColor(UIColor.blackColor(), forState: .Normal)
button1.setTitle("No", forState: .Normal)
button1.setImage(UIImage(named: "checkbox untick.png")!, forState: .Normal)
// if the selected button cannot be reclick again, you can use .Disabled state
button1.setImage(UIImage(named: "checkboxredtick.png")!, forState: .Selected)
button1.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside)
myStackview.addSubview(button1)
buttons.append(button1)
// create other buttons and add into buttons ...

func buttonAction(sender: UIButton!){
    for button in buttons {
        button.selected = false
    }
    sender.selected = true
    // you may need to know which button to trigger some action
    // let buttonIndex = buttons.indexOf(sender)
}

答案 1 :(得分:0)

我会为每个UIButton创建一个标记,然后添加要发送到ButtonAction的UIButton:

button.tag = 0
button.addTarget(object, action: #selector(YourViewController.buttonAction(_:)),
             forControlEvents: .TouchUpInside)


func buttonAction(sender: UIButton!) {
    let selectedButton = sender as! UIButton
    print(selectedButton.tag) // here stands the correct button which is pressed
}

您还可以创建一个包含所有按钮的数组,例如:

let myButtons = [UIButton]()
let button1 = UIButton()...
button1.tag = 0
myButtons.add(button1)

现在就像这样改变它:

myButtons[0].setImage(.....)

如果0是你的第一个按钮(所以标签为0)//你应该按照将它添加到myButtons数组的顺序设置你的标签。

答案 2 :(得分:0)

万一有人觉得有用。这是我如何使用DLRadioButton库(https://github.com/DavydLiu/DLRadioButton)动态创建RadioButton的示例。 您可以在此处https://github.com/omhack/DynamicRadioButtons

中查看一个完整的小型项目以显示有效代码。
import UIKit
import DLRadioButton

//Delegate to manage the Polls
protocol QuestionsDialogDelegate : class{
    func questionsAnswered(polls: [Poll])
}

class QuestionsDialog: UIViewController {

    @IBOutlet weak var stackView: UIStackView!
    @IBOutlet var rootView: UIView!
    @IBOutlet weak var nestedView: UIView!
    weak var delegate: QuestionsDialogDelegate?
    var questions : [Question]!
    var polls = [Poll]()
    var serviceType : Int = 0
    var indexView : Int = 0


    override func viewDidLoad() {
        super.viewDidLoad()
        //setting the stack view properties
        stackView.alignment = UIStackViewAlignment.leading
        stackView.axis = .vertical

    }

    //this is where the heavy logic, to create the dynamic radio buttons takes place
    func showQuestions(){

        if(questions.count <= 1){
            rootView.frame.size.height = 200
            nestedView.frame.size.height = 200
        }else{
            rootView.frame.size.height = 400
            nestedView.frame.size.height = 400
        }

        for question in questions{
            var otherButtons : [DLRadioButton] = []

            let frame1 = CGRect(x: self.view.frame.size.width / 2 - 131, y: 350, width: 262, height: 17);
            //we create a base radio button to use it as an anchor view
            let firstRadioButton = createRadioButton(frame: frame1, title: "", color: UIColor.purple);

            let label = UILabel()
            label.textAlignment = .center
            label.font = UIFont.boldSystemFont(ofSize: 17.0)
            label.textColor = UIColor.darkGray.withAlphaComponent(0.85)
            label.adjustsFontSizeToFitWidth = true
            label.minimumScaleFactor = 0.25
            label.frame = CGRect(x: 0, y: 0, width: 200, height: 30)
            label.text = question.question

            self.stackView.insertArrangedSubview(label, at: self.indexView)

            self.indexView += 1
            let poll = Poll()
            poll.idQuestion = question.idQuestion

            var i = 0;
            for answer in question.answers{

                let frame = CGRect(x: self.view.frame.size.width / 2 - 131, y: 380 + 30 * CGFloat(i), width: 300, height: 17);
                let radioButton = createRadioButton(frame: frame, title: answer.answer! + " ", color: UIColor.purple)
                radioButton.tag = answer.idAnswer
                radioButton.params["poll"] = poll
                otherButtons.append(radioButton)
                self.stackView.insertArrangedSubview(radioButton, at: self.indexView)
                i += 1;
                self.indexView += 1
            }


            firstRadioButton.otherButtons = otherButtons
            firstRadioButton.isHidden = true
            firstRadioButton.otherButtons[1].isSelected = true

        }
    }

    //Method to create a custom button
    private func createRadioButton(frame : CGRect, title : String, color : UIColor) -> MyDLUIButton {
        let radioButton = MyDLUIButton(frame: frame);
        radioButton.titleLabel?.translatesAutoresizingMaskIntoConstraints = false
        radioButton.titleLabel!.font = UIFont.systemFont(ofSize: 14);
        radioButton.setTitle(title, for: []);
        radioButton.setTitleColor(UIColor.darkGray, for: []);
        radioButton.iconColor = color;
        radioButton.indicatorColor = color;
        radioButton.contentHorizontalAlignment = UIControlContentHorizontalAlignment.left;
        radioButton.addTarget(self, action: #selector(QuestionsDialog.selectedAnswer(_:)), for: UIControlEvents.touchUpInside)
        self.view.addSubview(radioButton);

        return radioButton;
    }


    @objc func selectedAnswer(_ sender: MyDLUIButton){

        let poll = sender.params["poll"] as? Poll
        poll?.idAnswer = sender.tag


        if let row = self.polls.index(where: {$0.idQuestion == poll?.idQuestion}) {
            self.polls[row] = poll!
        }else{
            self.polls.append(poll!)
        }


        print("polls size: \(self.polls.count)")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func viewDidDisappear(_ animated: Bool) {
        if(self.polls.count < self.questions.count){
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "questionsDialogDismissed"), object: nil)
        }
    }

    @IBAction func requestService(_ sender: UIButton) {
        delegate?.questionsAnswered(polls: self.polls)
    }

}

class  MyDLUIButton: DLRadioButton{
    var params: Dictionary<String, Any>
    override init(frame: CGRect) {
        self.params = [:]
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        self.params = [:]
        super.init(coder: aDecoder)
    }
}