在 UIKit 中,如何从 ViewController 重构按钮?

In UIKit, how do you refactor buttons from a ViewController?

我正在自学 UIKit,目前致力于以编程方式创建控件和其他视图。

我试图将按钮从 ViewController 重构到它们自己的视图中。

This 是我一直遵循的教程,并根据我自己的项目对其进行了调整。这就是我所拥有的:

ViewController.swift:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let buttonBar = ButtonBar(frame: CGRect(x: 0, y: 0, width: 400, height: 100), buttonAction: buttonWasPressed)
        view.addSubview(toolbar)

    }
    
    func buttonWasPressed() {
        print("Button Was Pressed")
    }
}

和重构后的按钮,ButtonBar.swift:

import UIKit

class ButtonBar: UIView {
    
    var buttonAction: (() -> Void)?
    
    init(frame: CGRect, buttonAction: @escaping() -> Void) {
        super.init(frame: frame)
        
        setup()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup()
    }

    private func setup() {
        
        let buttonA = UIButton(type: .system)
        buttonA.setTitle("A", for: .normal)
        buttonA.frame = CGRect(x:20, y:20, width: 100, height: 100)
        buttonA.addTarget(self, action: #selector(self.buttonWasPressed), for: .touchUpInside)
        addSubview(buttonA)
        
        // more buttons to come...
        
    }
    
    @objc func buttonWasPressed() {
        buttonAction?()
    }
    
}

按下按钮时,我希望从 ViewController 打印消息“按钮被按下”,但那没有发生。我做错了什么?

我对 UIKit、Swift 和 iOS 开发的了解有限。即使按照上面的教程进行操作,我仍然不完全理解这段代码应该如何工作。

最后,这是将大量按钮重构为单个视图的正确方法吗?

谢谢!

Refectore 的类似方法,

    class ViewController: UIViewController {

    let buttonA = CustomButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50), name: "A")
    let buttonB = CustomButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50), name: "B")
    let buttonC = CustomButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50), name: "C")

    lazy var stackView : UIStackView = {
        let stack = UIStackView()
        stack.translatesAutoresizingMaskIntoConstraints = false
        stack.axis = .horizontal
        stack.distribution = .fillEqually
        return stack
    }()
   
   override func viewDidLoad() {
       super.viewDidLoad()
       view.backgroundColor = .white
       view.addSubview(stackView)
       stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
       stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true

       stackView.addArrangedSubview(buttonA)
       stackView.addArrangedSubview(buttonB)
       stackView.addArrangedSubview(buttonC)
       addButtonActions()
   }
    
    func addButtonActions() {
        buttonA.buttonAction = {
            print("Button A pressed")
        }
        
        buttonB.buttonAction = {
            print("Button B pressed")
        }
        
        buttonC.buttonAction = {
            print("Button C pressed")
        }
    }

}

class CustomButton: UIButton {
    
    var buttonAction: (() -> ())? = nil
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    convenience init(frame: CGRect, name: String) {
        self.init(frame: frame)
        self.addTarget(self, action: #selector(buttonCPressed), for: .touchUpInside)
        self.setTitleColor(.black, for: .normal)
        self.backgroundColor = .gray
        self.setTitle(name, for: .normal)
        self.frame = frame
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @objc func buttonCPressed() {
        buttonAction?()
    }
    
}