简体   繁体   English

iOS Swift 协议和委托

[英]iOS Swift protocol & delegate

Why my delegation is not working?为什么我的代表团不工作?

With my sample the action button works when clicked, but for some reason it does not reach the didAction function in my second controller.在我的示例中,操作按钮在单击时起作用,但由于某种原因,它在我的第二个 controller 中没有达到 didAction function。

protocol HomeControllerDelegate: class {
    func didAction()
}

class HomeController: UIViewController {
    
    weak var delegate: HomeControllerDelegate?
    
    private let actionButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("Action", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .black
        button.setHeight(50)
        button.setWidth(100)
        button.addTarget(self, action: #selector(handleAction), for: .touchUpInside)
        return button
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view.addSubview(actionButton)
        actionButton.centerX(inView: view)
        actionButton.centerY(inView: view)
    }
    
    @objc func handleAction() {
        print("DEBUG: Handle Action Button delegate here....")
        delegate?.didAction()
    }
}
class SecondController: UIViewController {
    
    let homeController = HomeController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        homeController.delegate = self
    }
}

extension SecondController: HomeControllerDelegate {
    func didAction() {
        print("DEBUG: In SecondController - didAction()")
    }
}

Many thanks for the guidance, it has made me look at the fundamentals and also what to research.非常感谢您的指导,它使我了解了基础知识以及要研究的内容。

I have created the below which solves my problem.我创建了以下内容来解决我的问题。

A container controller that Instantiates two ViewControlers and sets them as childVC's一个容器 controller 实例化两个 ViewControler 并将它们设置为 childVC

Then created a protocol on FirstChildVC and SecondChildVC is the delegate然后在 FirstChildVC 上创建了一个协议,SecondChildVC 是委托

All is working now an I understand a lot better.现在一切正常,我明白了很多。

class ContainerController: UIViewController {
    
    let secondChildVC = SecondChildVC()
    let firstChildVC = FirstChildVC()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        addFirstChildVC()
        addSecondChildVC()
    }
    
    func addSecondChildVC(){
        addChild(secondChildVC)
        view.addSubview(secondChildVC.view)
        secondChildVC.didMove(toParent: self)
        setSecondChildVCConstraints()
    }
    
    func addFirstChildVC(){
        addChild(firstChildVC)
        view.addSubview(firstChildVC.view)
        firstChildVC.delegateActionButton = secondChildVC
        firstChildVC.didMove(toParent: self)
        setFirstChildVCConstraints()
    }
    
    func setFirstChildVCConstraints() {
        firstChildVC.view.translatesAutoresizingMaskIntoConstraints = false
        firstChildVC.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true
        firstChildVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
        firstChildVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
        firstChildVC.view.heightAnchor.constraint(equalToConstant: 200).isActive = true
    }
    
    func setSecondChildVCConstraints() {
        secondChildVC.view.translatesAutoresizingMaskIntoConstraints = false
        secondChildVC.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20).isActive = true
        secondChildVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
        secondChildVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
        secondChildVC.view.heightAnchor.constraint(equalToConstant: 200).isActive = true
    }
}
protocol FirstChildVCDelegate: class {
    func didAction(data: String)
}

class FirstChildVC: UIViewController {
    
    weak var delegateActionButton: FirstChildVCDelegate!
    
    private let actionButton: UIButton = {
        let button = UIButton(type: .system)
        let buttonHeight = 30
        button.setTitle("Button", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .black
        button.layer.cornerRadius = CGFloat(buttonHeight / 2)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.heightAnchor.constraint(equalToConstant: CGFloat(buttonHeight)).isActive = true
        button.translatesAutoresizingMaskIntoConstraints = false
        button.widthAnchor.constraint(equalToConstant: 100).isActive = true
        button.addTarget(self, action: #selector(handleAction), for: .touchUpInside)
        return button
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemPink
        configureActionButtonView()
    }
    
    func configureActionButtonView() {
        view.addSubview(actionButton)
        actionButton.translatesAutoresizingMaskIntoConstraints = false
        actionButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        actionButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }
    
    @objc func handleAction() {
        delegateActionButton.didAction(data: "Button Pressed")
    }
}

class SecondChildVC: UIViewController {
    
    private let actionButtonLabel: UILabel = {
        let label = UILabel()
        label.text = "test"
        label.font = .systemFont(ofSize: 18)
        label.textColor = .white
        label.isHidden = true
        return label
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemPurple
        configureActionButtonLabel()
    }
    
    func configureActionButtonLabel() {
        view.addSubview(actionButtonLabel)
        actionButtonLabel.translatesAutoresizingMaskIntoConstraints = false
        actionButtonLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        actionButtonLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }
}
extension SecondChildVC: FirstChildVCDelegate {
    func didAction(data: String) {
        actionButtonLabel.isHidden.toggle()
        actionButtonLabel.text = data
    }
}

Initial State初始 State

State once Button pressed State 一次按下按钮

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM