具有自定义 UIView(包括按钮)的 UIViewController 无法识别水龙头

UIViewController with custom UIView (that includes a button) doesn't recognize taps

当尝试以编程方式将包含 UIButton 的自定义 UIView (BaseHeader.swift) 加载到 UIViewController (ViewController.swift) 时,点击按钮 而不是 认可。

如果我提取自定义 UIView 中的代码并将其直接粘贴到 UIViewController 中,所有点击都会被识别并按预期工作。我错过了什么?

起初,我认为是 UIView 在实例化后没有定义框架大小的问题。尽管按预期显示,但我认为按钮可能没有 "hit box"。在给视图一个框架后,我仍然没有运气,在谷歌搜索了一段时间后尝试了各种其他的东西。

The view loads but button taps are not recognized -- see image

ViewController.swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.title = "Authentication"
    }

    override func loadView() {
        super.loadView()

        let header = BaseHeader()
        header.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(header)

        NSLayoutConstraint.activate([
            header.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
            header.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
            header.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: -10),
        ])
    }
}

BaseHeader.swift

import UIKit

class BaseHeader: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    func setupView() {

        self.isUserInteractionEnabled = true

        let avenirFont = UIFont(name: "Avenir", size: 40)
        let lightAvenirTitle = avenirFont?.light

        let title = UILabel()
        title.text = "Title"
        title.font = lightAvenirTitle
        title.textColor = .black
        title.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(title)

        NSLayoutConstraint.activate([
            title.topAnchor.constraint(equalTo: self.topAnchor, constant: 20),
            title.centerXAnchor.constraint(equalTo: self.centerXAnchor)
        ])


        let profile = UIButton()
        let profileImage = UIImage(named: "person-icon")
        profile.setImage(profileImage, for: .normal)
        profile.setImage(UIImage(named: "think-icon"), for: .highlighted)
        profile.addTarget(self, action: #selector(profileTapped), for: .touchUpInside)
        profile.backgroundColor = .systemBlue
        profile.frame.size = CGSize(width: 30, height: 30)
        profile.isUserInteractionEnabled = true
        profile.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(profile)

        NSLayoutConstraint.activate([
            profile.centerYAnchor.constraint(equalTo: title.centerYAnchor),
            profile.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20),
        ])
    }

    @objc func profileTapped(sender: UIButton) {
        print("Tapped")
    }
}

可能是您为自定义视图调用了错误的初始值设定项,并且未调用您的 setupView() 函数。看起来在您调用的视图控制器中

let header = BaseHeader()

要初始化视图,不过是这个init:

override init(frame: CGRect) {
    super.init(frame: frame)
    setupView()
}

这会调用您的 setupView() 函数并设置水龙头。

您忘记为 BaseHeader 设置高度

 NSLayoutConstraint.activate([
            header.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
            header.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
            header.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: -10),
header.heightAnchor.constraint(equalToConstant: 40) //add more
        ])