Копия UiView и всех подпредставлений .. Нажатую кнопку UIB нельзя нажимать - PullRequest
0 голосов
/ 25 декабря 2018

По сути, я использую это расширение кода ниже, чтобы скопировать представление и все его подпредставления.Копирование выполнено успешно, и я могу просмотреть скопированное представление.Однако кнопка на каждом скопированном виде не может быть нажата.Кнопка может быть нажата только в пределах первого исходного (не скопированного) вида.Как заставить все скопированные кнопки быть активными?Это вообще возможно?

Я уже пробовал .isUserInteractionEnabled на кнопке и ее родительском представлении.

override func viewDidLoad(){
    super.viewDidLoad()
    view.isUserInteractionEnabled = true
    view.addSubview(containerScrollView)
    containerScrollView.addSubview(contentView)
    contentView.addSubview(stackMainView)
    let button = UIButton(frame: CGRect(x: 270, y: 200, width: 80, height: 40))
    let partLabel1 = UILabel(frame: CGRect(x:10, y: 10, width: 300, height: 50))
    let partLabel2 = UILabel(frame: CGRect(x:10, y: 50, width: 300, height: 50))
    partLabel1.text = "This should sit within part use :)"
    partLabel1.textColor = .white
    partLabel2.text = "This should also sit within part use :)"
    partLabel2.textColor = .white
    contentView.addSubview(button)
    contentView.addSubview(partLabel1)
    contentView.addSubview(partLabel2)
    part.addSubview(button)
    part.addSubview(partLabel1)
    part.addSubview(partLabel2)
    part.bringSubviewToFront(button)
    part.bringSubviewToFront(partUse3Label1)
    part.layer.zPosition = -1
    button.setTitle("Issue", for: .normal)
    button.backgroundColor = .orange
    button.leadingAnchor.constraint(equalTo: part.leadingAnchor).isActive = true
    button.trailingAnchor.constraint(equalTo: part.trailingAnchor).isActive = true
    button.bottomAnchor.constraint(equalTo: part.bottomAnchor).isActive = true
    button.topAnchor.constraint(equalTo: part.topAnchor).isActive = true
    button.heightAnchor.constraint(equalToConstant: 40).isActive = true
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
    button.isUserInteractionEnabled = true
    part.bringSubviewToFront(button)
    partLabel1.leadingAnchor.constraint(equalTo: part.leadingAnchor).isActive = true
    partLabel1.trailingAnchor.constraint(equalTo: part.trailingAnchor).isActive = true
    partLabel2.leadingAnchor.constraint(equalTo: part.leadingAnchor).isActive = true
    partLabel2.trailingAnchor.constraint(equalTo: part.trailingAnchor).isActive = true
    part.layoutIfNeeded()

    let copiedView = self.part.copyView()
    stackMainView.addArrangedSubview(part)
    stackMainView.addArrangedSubview(copiedView)
    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
    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

    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

}



@objc func buttonAction(sender: UIButton!) {
    print("Button tapped")
}

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

}()



let part: UIView  = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints  = false
    view.layer.cornerRadius = 4
    view.layer.masksToBounds = true
    view.backgroundColor = .random()

    return view
}()

Расширение для копирования представления.

extension UIView {
    func copyView<T: UIView>() -> T {
        return NSKeyedUnarchiver.unarchiveObject(with: 
               NSKeyedArchiver.archivedData(withRootObject: self)) as! T
    }
}

Я ожидаю, что вывод будет напечатан в консоли «Нажатие кнопки» Это происходит, только когда я нажимаю кнопку в не скопированном представлении,

1 Ответ

0 голосов
/ 25 декабря 2018

Поскольку все это делается в viewDidLoad, я предполагаю, что представление, которое вы хотите скопировать, всегда одинаково.

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

Вы можете создать метод, который вместо этого выдаст новый UIView:

func createPart() -> UIView {
    let part = UIView()
    part.translatesAutoresizingMaskIntoConstraints  = false
    part.layer.cornerRadius = 4
    part.layer.masksToBounds = true
    part.backgroundColor = .random()

    // The part below is copied from your viewDidLoad method
    // Include only those lines that create the part view.
    // I might have put more than you need. Check twice
    let button = UIButton(frame: CGRect(x: 270, y: 200, width: 80, height: 40))
    let partLabel1 = UILabel(frame: CGRect(x:10, y: 10, width: 300, height: 50))
    let partLabel2 = UILabel(frame: CGRect(x:10, y: 50, width: 300, height: 50))
    partLabel1.text = "This should sit within part use :)"
    partLabel1.textColor = .white
    partLabel2.text = "This should also sit within part use :)"
    partLabel2.textColor = .white
    part.addSubview(button)
    part.addSubview(partLabel1)
    part.addSubview(partLabel2)
    part.bringSubviewToFront(button)
    part.bringSubviewToFront(partUse3Label1)
    part.layer.zPosition = -1
    button.setTitle("Issue", for: .normal)
    button.backgroundColor = .orange
    button.leadingAnchor.constraint(equalTo: part.leadingAnchor).isActive = true
    button.trailingAnchor.constraint(equalTo: part.trailingAnchor).isActive = true
    button.bottomAnchor.constraint(equalTo: part.bottomAnchor).isActive = true
    button.topAnchor.constraint(equalTo: part.topAnchor).isActive = true
    button.heightAnchor.constraint(equalToConstant: 40).isActive = true
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
    button.isUserInteractionEnabled = true
    part.bringSubviewToFront(button)
    partLabel1.leadingAnchor.constraint(equalTo: part.leadingAnchor).isActive = true
    partLabel1.trailingAnchor.constraint(equalTo: part.trailingAnchor).isActive = true
    partLabel2.leadingAnchor.constraint(equalTo: part.leadingAnchor).isActive = true
    partLabel2.trailingAnchor.constraint(equalTo: part.trailingAnchor).isActive = true
    part.layoutIfNeeded()

    return part
}

А затем в viewDidLoad вы должны удалить строки кода, которые помогают создатьpart представление, оставляя только код, который создает представление стека и представление основного содержимого.Затем вам следует дважды позвонить createPart, и у вас будет 2 копии!

let part = createPart()
let copyOfPart = createPart()
...