【问题标题】: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()
    }

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

【问题讨论】:

    标签: ios objective-c swift autolayout constraints


    【解决方案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 因为上面的代码不支持旋转。
    猜你喜欢
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 2020-09-23
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多