Добавление представлений с подпредставлениями программно, в цикле - PullRequest
0 голосов
/ 15 января 2019

Ссылка на этот вопрос здесь при копировании представлений с подпредставлениями Копия UiView и всех подпредставлений .. Нажатую кнопку UIB нельзя нажимать

В приведенной выше ссылке возможно копирование представления и всех его подпредставлений, однако мне не удалось создать цикл, который будет создавать столько же или меньше представлений.

Моя попытка добавить представления в представление стека, которое находится внутри представления прокрутки, чтобы вы могли прокрутить вниз, если требуется много представлений:

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 голосов
/ 15 января 2019

Вы, конечно, можете сделать это с помощью прокрутки и просмотра стека.

Ваша основная проблема заключалась в том, что вы создаете свою "деталь" вне цикла 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

    }()
}

Примечание: если вы считаете, что вам могут понадобиться партии деталей, вам, вероятно, лучше использовать табличное представление и проектировать "деталь" как ячейку многократного использования.

0 голосов
/ 15 января 2019

Да, вы можете проходить и создавать несколько элементов.

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. Это работает для вас?

...