快速动态添加按钮

Posted

技术标签:

【中文标题】快速动态添加按钮【英文标题】:Dynamically add buttons in swift 【发布时间】:2017-06-07 09:58:45 【问题描述】:

我正在编写一个 ios 应用程序。服务器给了我按钮数组来绘制视图。因此,按钮的数量可能会根据服务器响应而有所不同, 示例:

let buttonArray=["Button 1","Button 2","Button 3"]
or
let buttonArray=["Button 1","Button 2","Button 3"," Button 4", "Button 5"]

我必须垂直堆叠这些按钮。 我创建了一个stackview,向其中添加constraints,然后add 按钮作为arrangedsubviews 到这个stackview。 按钮之间应该有 5 个点的差距

使用堆栈视图:

func addButtonsUsingStackView()
    
        //create stackview:
        let stackView=UIStackView()
        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        stackView.alignment = .fill
        stackView.spacing = 5
        stackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stackView)

        //stackview constraints:
        let viewsDictionary = ["stackView":stackView]
        let stackView_H = NSLayoutConstraint.constraints(
            withVisualFormat: "H:|-20-[stackView]-20-|",
            options: NSLayoutFormatOptions(rawValue: 0),
            metrics: nil,
            views: viewsDictionary)
        let stackView_V = NSLayoutConstraint.constraints(
            withVisualFormat: "V:|-30-[stackView]-30-|",
            options: NSLayoutFormatOptions(rawValue:0),
            metrics: nil,
            views: viewsDictionary)
        view.addConstraints(stackView_H)
        view.addConstraints(stackView_V)

        //adding buttons to stackview:

        //let buttonArray=["Button 1","Button 2","Button 3"]
        let buttonArray=["Button 1","Button 2","Button 3"," Button 4"]

        for buttonName in buttonArray

            let button=UIButton()
            button.setTitle(buttonName, for: .normal)
            button.setTitleColor(UIColor.white, for: .normal)
            button.backgroundColor=UIColor.blue
            button.translatesAutoresizingMaskIntoConstraints=false

            stackView.addArrangedSubview(button)

        

    

没有堆栈视图:

var buttonArray=["Button 1","Button 2","Button 3"," Button 4"," Button 5"," Button 6"," Button 7"]

    func addButtonsLoop()
    

        for _view in view.subviews
            _view.removeFromSuperview()
        

        var i=0
        var buttonY = 20
        let buttonGap=5

        for btn in buttonArray 

            let buttonHeight=Int(Int(view.frame.height) - 40 - (buttonArray.count * buttonGap))/buttonArray.count
            print(buttonHeight)
            let buttonWidth=Int(view.frame.width - 40)

            let button = UIButton()
            button.backgroundColor = UIColor.orange
            button.setTitle(btn, for: .normal)
            button.titleLabel?.textColor = UIColor.white
            button.frame = CGRect(x: 20, y: buttonY, width:buttonWidth , height:buttonHeight)
            button.contentMode = UIViewContentMode.scaleToFill
            buttonY += buttonHeight + buttonGap
            button.tag = i
            button.addTarget(self, action: #selector(self.buttonTapped(_:)), for: UIControlEvents.touchUpInside)
            view.addSubview(button)

            i+=1

        
    

    func buttonTapped( _ button : UIButton)
    
        buttonArray.remove(at: button.tag)
        addButtonsLoop()
    

我的问题是,除了上面的代码,如何应用 NSLayoutConstraintsLayoutAnchors 来解决这个问题?

【问题讨论】:

【参考方案1】:

您可以使用包含按钮的表格视图单元格而不是堆栈视图,并且行数可以是按钮数组计数。在cellForRowAtIndexPath委托方法中,从按钮数组中设置按钮标题。

【讨论】:

不使用tableView和stackview能告诉我吗? 如果您不想使用 tableview 的任何一个 stackview 那么您必须计算每个按钮的框架并将这些按钮添加到视图中。 如果点击按钮,它会从视图中移除,我应该如何保持约束? 如果您不想再次显示该按钮,那么在 IBAction 上,您可以从 ButtonArray 中删除该点击的按钮并调用您编写的函数来放置按钮。抱歉,在这里我强烈建议您使用 tableview/stackview,因为这些类型的添加和删除很容易,并且在使用 tableview 时,如果有足够数量的按钮,您可以有效地管理滚动。 谢谢,推荐使用tableView,但我的问题是不使用任何控件。在不使用其中任何一个的情况下,我想添加动态按钮以查看它们之间有 5 个点的差距,并且在点击按钮时它会从视图中删除,但是约束不应该失败。!【参考方案2】:

您可以使用滚动视图来添加按钮。

var btnY = 5
let btnHeight = 40
func addButtonsUsingStackView()
        
    for view in self.view.subviews
                view.removeFromSuperview()
            

            for i in 0..< buttonArray.count 

                let btnFloor = UIButton()
                btnFloor.backgroundColor = Orange       
                btnFloor.titleLabel?.textColor = UIColor.white
                btnFloor.frame = CGRect(x: 10, y: btnY, width: Int(scrView.frame.width - 20), height: btnHeight)
                btnFloor.contentMode = UIViewContentMode.scaleToFill
                btnY += btnHeight + 5
                btnFloor.tag = buttonArray.index(of: i)
                btnFloor.addTarget(self, action: #selector(self.btnTappedFloor(_:)), for: UIControlEvents.touchUpInside)
                self.view.addSubview(btnFloor)
            
            return cell
        

 func btnTappedFloor( _ button : UIButton)
 
      buttonArray.remove(at: button.tag)
      addButtonsUsingStackView()

【讨论】:

你能告诉我不使用 tableView 或 scrollView 或 stackview 吗? 不使用任何这些,我想添加动态按钮以查看它们之间有 5 个点的差距,并且在点击按钮时它会从视图中删除,但是约束不应该失败。! btnFloorHeight? 非常感谢。我根据你的回答修改了我的问题。现在,有没有更优化的方法来解决这个问题?而不是上面的代码,我怎么能使用 NSLayoutConstraints 或 LayoutAnchors 因为上面的代码不支持旋转。 让我们continue this discussion in chat。

以上是关于快速动态添加按钮的主要内容,如果未能解决你的问题,请参考以下文章

除非快速选择所有单元格,否则限制表格视图

快速将文本字段添加到 UITableViewCell

如何动态添加按钮?

MFC SDI中 如何为动态创建的按钮添加消息处理函数

将 jQueryui 按钮添加到动态添加的内容

点击事件不适用于动态添加的按钮