以编程方式循环添加带有子视图的视图

时间:2019-01-15 18:54:31

标签: ios swift dynamic copy

在复制带有子视图Copy of UiView and all subviews..Copied UIButton cannot be pressed的视图时参考此问题

在上面的链接中,可以复制一个视图及其所有子视图,但是,我创建一个循环会失败,该循环将创建尽可能多或更少的视图。

我一直试图将视图添加到滚动视图内部的堆栈视图中,以便在需要多个视图时可以向下滚动:

var numOfViewsNeeded = 5

func createPart() -> UIView {
    let part = UIView()
    part.translatesAutoresizingMaskIntoConstraints  = false
    part.layer.cornerRadius = 4
    part.layer.masksToBounds = true
    part.backgroundColor = .random()
    part.heightAnchor.constraint(equalToConstant: 300).isActive = true

    let partLabel1 = UILabel(frame: CGRect(x:10, y: 0, width: 300, height: 50))
    let partLabel2 = UILabel(frame: CGRect(x:10, y: 35, width: 300, height: 50))
    let partLabel3 = UILabel(frame: CGRect(x:10, y: 75, width: 300, height: 50))
    let partLabel4 = UILabel(frame: CGRect(x:10, y: 115, width: 300, height: 50))
    let partLabel5 = UILabel(frame: CGRect(x:10, y: 155, width: 300, height: 50))
    let partLabel6 = UILabel(frame: CGRect(x:10, y: 195, width: 300, height: 50))
    partLabel1.text = "NO."
    partLabel1.textColor = .white
    partLabel2.text = "Code"
    partLabel2.textColor = .white
    partLabel3.text = "Br"
    partLabel3.textColor = .white
    partLabel4.text = "Stat"
    partLabel4.textColor = .white
    partLabel5.text = "Line"
    partLabel5.textColor = .white
    partLabel6.text = "B"
    partLabel6.textColor = .white

    part.addSubview(partLabel1)
    part.addSubview(partLabel2)
    part.addSubview(partLabel3)
    part.addSubview(partLabel4)
    part.addSubview(partLabel5)
    part.addSubview(partLabel6)

    part.layer.zPosition = -1]
    return part
}

override func viewDidLoad() {
    super.viewDidLoad()
    let part = createPart()
     for i in 0..<numOfViewsNeeded {
         view.addSubview(part)
         stackView.addArrangedSubview(part)
      }
    contentView.topAnchor.constraint(equalTo: self.containerScrollView.topAnchor, constant: 0).isActive = true
    contentView.leadingAnchor.constraint(equalTo: self.containerScrollView.leadingAnchor, constant: 0).isActive = true
    contentView.trailingAnchor.constraint(equalTo:self.containerScrollView.trailingAnchor, constant: 0).isActive = true
    contentView.bottomAnchor.constraint(equalTo: self.containerScrollView.bottomAnchor, constant: 0).isActive = true
    contentView.widthAnchor.constraint(equalTo:self.view.widthAnchor, constant: 0).isActive = true
    containerScrollView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
    containerScrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0).isActive = true


containerScrollView.trailingAnchor.constraint(equalTo:self.view.trailingAnchor, constant: 0).isActive = true
    containerScrollView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
    stackMainView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 50).isActive = true
    stackMainView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 8).isActive = true
    stackMainView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -8).isActive = true
    //stackMainView.heightAnchor.constraint(equalToConstant: CGFloat(self.heighOfStack)).isActive = true
    stackMainView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -30).isActive = true
    }

var containerScrollView: UIScrollView = {
    let scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints  = false
    scrollView.backgroundColor = .white
    scrollView.isScrollEnabled = true
    return scrollView
}()

var contentView: UIView = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints  = false
    view.backgroundColor = UIColor.white
    return view
}()
let stackMainView: UIStackView = {
    let stackView = UIStackView()
    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.backgroundColor = .random()
    return stackView

}()

这种“动态地”反复创建相同视图的过程是否可能?

对此将提供任何帮助!

2 个答案:

答案 0 :(得分:1)

您当然可以使用滚动视图和堆栈视图来做到这一点。

您的主要问题是您正在创建for循环的“部分” 外部

    // this creates ONE part view
    let part = createPart()
    // your loop simply adds and re-adds that one part view
    for i in 0..<numOfViewsNeeded {
        view.addSubview(part)
        stackView.addArrangedSubview(part)
    }

它应该像这样:

    for i in 0..<numOfViewsNeeded {
        // create a new part view
        let part = createPart()
        // add that new view to the stack view
        stackView.addArrangedSubview(part)
    }

这是您代码的修改版本,可以为您提供所需的结果:

class AddStuffViewController: UIViewController {

    var numOfViewsNeeded = 5

    var bkgColors: [UIColor] = [
        .blue,
        .green,
        .red,
        .orange,
        .yellow
    ]

    func createPart(_ n: Int) -> UIView {
        let part = UIView()
        part.translatesAutoresizingMaskIntoConstraints  = false
        part.layer.cornerRadius = 4
        part.layer.masksToBounds = true
        part.backgroundColor = bkgColors[n] // .random()
        part.heightAnchor.constraint(equalToConstant: 300).isActive = true

        let partLabel1 = UILabel(frame: CGRect(x:10, y: 0, width: 300, height: 50))
        let partLabel2 = UILabel(frame: CGRect(x:10, y: 35, width: 300, height: 50))
        let partLabel3 = UILabel(frame: CGRect(x:10, y: 75, width: 300, height: 50))
        let partLabel4 = UILabel(frame: CGRect(x:10, y: 115, width: 300, height: 50))
        let partLabel5 = UILabel(frame: CGRect(x:10, y: 155, width: 300, height: 50))
        let partLabel6 = UILabel(frame: CGRect(x:10, y: 195, width: 300, height: 50))
        partLabel1.text = "NO."
        partLabel1.textColor = .white
        partLabel2.text = "Code"
        partLabel2.textColor = .white
        partLabel3.text = "Br"
        partLabel3.textColor = .white
        partLabel4.text = "Stat"
        partLabel4.textColor = .white
        partLabel5.text = "Line"
        partLabel5.textColor = .white
        partLabel6.text = "B"
        partLabel6.textColor = .white

        part.addSubview(partLabel1)
        part.addSubview(partLabel2)
        part.addSubview(partLabel3)
        part.addSubview(partLabel4)
        part.addSubview(partLabel5)
        part.addSubview(partLabel6)

        return part
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(containerScrollView)
        containerScrollView.addSubview(contentView)
        contentView.addSubview(stackMainView)

        for i in 0..<numOfViewsNeeded {
            let part = createPart(i)
            stackMainView.addArrangedSubview(part)
        }

        contentView.topAnchor.constraint(equalTo: self.containerScrollView.topAnchor, constant: 0).isActive = true
        contentView.leadingAnchor.constraint(equalTo: self.containerScrollView.leadingAnchor, constant: 0).isActive = true
        contentView.trailingAnchor.constraint(equalTo:self.containerScrollView.trailingAnchor, constant: 0).isActive = true
        contentView.bottomAnchor.constraint(equalTo: self.containerScrollView.bottomAnchor, constant: 0).isActive = true

        contentView.widthAnchor.constraint(equalTo:self.containerScrollView.widthAnchor, constant: 0).isActive = true

        containerScrollView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
        containerScrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0).isActive = true
        containerScrollView.trailingAnchor.constraint(equalTo:self.view.trailingAnchor, constant: 0).isActive = true
        containerScrollView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true

        stackMainView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 50).isActive = true
        stackMainView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 8).isActive = true
        stackMainView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -8).isActive = true
        stackMainView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -30).isActive = true


    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print(stackMainView.arrangedSubviews.count)
    }

    var containerScrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints  = false
        scrollView.backgroundColor = .gray
        scrollView.isScrollEnabled = true
        return scrollView
    }()

    var contentView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints  = false
        view.backgroundColor = .cyan
        return view
    }()
    let stackMainView: UIStackView = {
        let stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        return stackView

    }()
}

注意:如果您认为需要很多个零件,则最好使用表格视图并将“零件”设计为可重复使用的单元格。

答案 1 :(得分:-1)

是的,您可以遍历并创建多个项目。

let yArray = [0, 35, 75, 115, 155, 195]
let textArray ["NO.", "Code", "Br", "Stat", "Line", "B"]

var numOfViewsNeeded = 5

func createPart() -> UIView {
    let part = UIView()
    part.translatesAutoresizingMaskIntoConstraints  = false
    part.layer.cornerRadius = 4
    part.layer.masksToBounds = true
    part.backgroundColor = .random()
    part.heightAnchor.constraint(equalToConstant: 300).isActive = true

    for index in 0...numOfViewNeeded-1 {
        let partLabel = UILabel(frame: CGRect(x:10, y: yArray[index], width: 300, height: 50))
        partLabel.text = "\(textArray[index])"
        partLabel.textColor = .white
        part.addSubview(partLabel)
    }

    part.layer.zPosition = -1
    return part
}

这是不使用tableView或stackView的。这对您有用吗?