Array of UIButtons in Swift 4

和自甴很熟 提交于 2020-08-25 03:47:20

问题


I've made a series of checkboxes in UiKit with UIButtons:

@IBOutlet weak var Box1: UIButton!
@IBOutlet weak var Box2: UIButton!
@IBOutlet weak var Box3: UIButton!
....
@IBOutlet weak var Box59: UIButton!




// Gives the button an action
@IBAction func Box1(_ sender: UIButton) {
    sender.isSelected = !sender.isSelected
}
@IBAction func Box2(_ sender: UIButton) {
    sender.isSelected = !sender.isSelected
}
@IBAction func Box3(_ sender: UIButton) {
    sender.isSelected = !sender.isSelected
}
    ....
@IBAction func Box59(_ sender: UIButton) {
    sender.isSelected = !sender.isSelected
}




// Creates button images of checkbox and unchecked box
var BoxON = UIImage(named: "CheckBox")
var BoxOFF = UIImage(named:"UnCheckBox")




// Allows the button to be set to the image, if selected or not 
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    Box1.setImage(BoxOFF, for: .normal)
    Box1.setImage(BoxON, for: .selected)

    Box2.setImage(BoxOFF, for: .normal)
    Box2.setImage(BoxON, for: .selected)

    Box3.setImage(BoxOFF, for: .normal)
    Box3.setImage(BoxON, for: .selected)
    ....
    Box59.setImage(BoxOFF, for: .normal)
    Box59.setImage(BoxON, for: .selected)

    }

This is all the code necessary to make as many checkboxes as possible. However, each checkbox requires creating/moving a button to the right spot on the storyboard, linking the button from the storyboard to the button variable that was just coded. This can take a lot of time since I need over 100 buttons per view controller.

Is there a faster way to do this by making an array of buttons? or something similar?


回答1:


It is possible to declare an IBOutlet as array

  • Create an IBOutlet as array

    @IBOutlet var boxes : [UIButton]!
    
  • Connect all buttons to the same outlet (in the desired order)

  • In viewDidAppear use a loop or forEach

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    
        boxes.forEach {
            $0.setImage(BoxOFF, for: .normal)
            $0.setImage(BoxON, for: .selected)
        }
    }
    
  • Add unique tags to the buttons (optional).

  • Create one IBAction and connect all buttons to the action
  • Use a switch statement to distinguish the buttons by index in the array or by tag

    @IBAction func boxTouched(_ sender: UIButton) {
        sender.isSelected = !sender.isSelected
        let index = boxes.index(of: sender)!
        switch index {
           // handle the cases
        }
    }
    
    @IBAction func boxTouched(_ sender: UIButton) {
        sender.isSelected = !sender.isSelected
        switch sender.tag {
           // handle the cases
        }
    }
    



回答2:


I have created array of checkboxes(buttons) along with text(labels). You can select and deselect any button.

func addCheckBoxButtonsForSecondContainerView ()
{
    var xPosition = 0
    var yPosition = 0
    for i in 0..<likedArray.count
           {
               let secondViewCheckBox = UIButton(frame: CGRect(x: xPosition, y: yPosition, width: 18, height: 18))
               secondViewCheckBox.layer.borderWidth = 1
               secondViewCheckBox.layer.borderColor = UIColor(red: 1.0 / 255.0, green: 202.0 / 255.0, blue: 91.0 / 255.0, alpha: 1.0).cgColor
               secondViewCheckBox.addTarget(self, action: #selector(secondViewButtonAction(_:)), for: .touchUpInside)
               secondViewCheckBox.tag = i
               secondViewCheckBox.layer.cornerRadius = 2
               self.secondContainerView.addSubview(secondViewCheckBox)//adding button to container view
            //In the below line I'm creating label for title.
            let labelTitle = UILabel(frame: CGRect(x: xPosition+25, y: yPosition, width: 130, height: 18))  //UIButton(frame: CGRect(x: xPosition+30, y: yPosition, width: 100, height: 18))
            labelTitle.text = "  " + self.likedArray[i]
            labelTitle.font = UIFont.RummyLatoRegular(size: 12)
            labelTitle.tag = secondViewCheckBox.tag
            labelTitle.textAlignment = .left
            labelTitle.isUserInteractionEnabled = true
            labelTitle.textColor = UIColor.white
            labelTitle.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(secondViewLabelAction(_:))))
            self.secondContainerView.addSubview(labelTitle)//adding label to the containerview

            if i != 0 && (i+1)%3 == 0
            {
                xPosition = 0
                yPosition = Int(secondViewCheckBox.frame.origin.y+secondViewCheckBox.frame.size.height+15)
            }
            else
            {
                xPosition += 160
            }
           }
    
}

//Next we see here action for the buttons(checkboxes)

 @objc func secondViewButtonAction(_ sender: UIButton)
   {
    if arrayofSelectedIndexes.contains(sender.tag)
    {
        for i in 0..<arrayofSelectedIndexes.count
        {
            if arrayofSelectedIndexes[i] == sender.tag
            {
                arrayofSelectedIndexes.remove(at: i)
                sender.setBackgroundImage(UIImage.init(named: ""), for: .normal)
                break
            }

        }
    }
    else
    {
        arrayofSelectedIndexes.append(sender.tag)
        sender.setBackgroundImage(UIImage.init(named: "npsTickIcon"), for: .normal)
    }

}

//this is for title label action

 @objc func secondViewLabelAction(_ sender: UITapGestureRecognizer)
      {
        for subview in self.secondContainerView.subviews {
            if let button = subview as? UIButton {
                let searchlbl:UILabel = (sender.view as! UILabel) //just to get sender tag
                if searchlbl.tag == subview.tag
                {
                    if arrayofSelectedIndexes.contains(searchlbl.tag)
                    {
                        for i in 0..<arrayofSelectedIndexes.count
                        {
                            if arrayofSelectedIndexes[i] == searchlbl.tag
                            {
                                arrayofSelectedIndexes.remove(at: i)
                                button.setBackgroundImage(UIImage.init(named: ""), for: .normal)
                                break
                            }
                        }
                    }
                    else{
                        arrayofSelectedIndexes.append(searchlbl.tag)
                    button.setBackgroundImage(UIImage.init(named: "npsTickIcon"), for: .normal)
                    }
                }
                
            }
        }

Let me know if you need more clarification. User can click on button or title label. Same action will be performed. I'm attaching the screenshot here for output. [1]: https://i.stack.imgur.com/cXoww.png



来源:https://stackoverflow.com/questions/50068413/array-of-uibuttons-in-swift-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!