具有自定义 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
])
当尝试以编程方式将包含 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
])