【问题标题】:iOS Swift protocol & delegateiOS Swift 协议和委托
【发布时间】:2021-03-14 11:11:27
【问题描述】:

为什么我的代表团不起作用?

在我的示例中,操作按钮在单击时起作用,但由于某种原因,它没有到达我的第二个控制器中的 didAction 函数。

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()")
    }
}

【问题讨论】:

  • 因为let homeController = HomeController() 是错误的 HomeController。 programmingios.net/dont-make-a-new-instance-by-mistake
  • 调试:当delegate?.didAction()被调用时,是delegatenil吗?这是迈出的一大步。现在,有了更多经验:homeController 它在哪里展示?我认为屏幕上显示的那个和设置了delegate 的那个不是同一个实例。
  • 作为调试提示.... delegate?.didAction() 中的 ? 表示“我不在乎是否会发生这种情况”。如果它不是你想要的,你不应该这样编码。
  • 感谢您的指导,是的,我知道这是一个基本问题,而且一分钱正在慢慢下降,这是一个基本问题!我现在将创建控制器并将它们添加到我的根控制器。感谢马特的链接!我有。很多东西要学,还有很长的路要走。问题是我参加了一些 Udemy 课程,现在我正在尝试自己尝试,似乎有些基础知识没有得到解释,或者我可能误解了。在线课程不如亲自上课,我确实在网上挣扎。但是我现在已经购买了一些关于 hackingwith swift 的书籍,并且会继续关注

标签: ios swift delegates


【解决方案1】:

非常感谢您的指导,它让我了解了基础知识以及要研究的内容。

我创建了以下内容来解决我的问题。

实例化两个 ViewControler 并将它们设置为 childVC 的容器控制器

然后在 FirstChildVC 上创建了一个协议,SecondChildVC 是委托

现在一切正常,我明白了很多。

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 once Button pressed

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多