我为视图控制器实现了标头(UIView),但我无法为 UIView 内部的按钮添加目标。我相信这对每个人来说都很容易理解,但如果您愿意,我可以添加更多细节
loadView() 内的我的视图控制器代码
let headerViewModel = HeaderViewModel(title: "Farmers", helpAction: {self.navigationController?.popViewController(animated: true) // when debugging this //line doesn't work when adding })
let headerView = HeaderView(viewModel: headerViewModel)
我的标题 UIView 代码
import UIKit
protocol HeaderViewModelProtocol {
var title: String { get }
var color: UIColor { get }
var imageName: String? { get }
var backAction: (()->Void)? { get set}
var helpAction: (()->Void)? { get set}
}
struct HeaderViewModel: HeaderViewModelProtocol {
let title: String
var color: UIColor = UIColor.white
var imageName: String?
var backAction: (() -> Void)?
var helpAction: (() -> Void)?
}
class HeaderView: UIView {
let viewModel: HeaderViewModelProtocol
private var layer0: CAGradientLayer!
var backButton: UIButton = {
let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
button.addTarget(HeaderView.self, action: #selector(tapBack), for: .touchUpInside)
button.backgroundColor = UIColor.red
button.tag=5
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .clear
button.tintColor = .white
button.setImage(UIImage(named: "back"), for: .normal)
return button
}()
var helpButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .clear
button.setImage(UIImage(named: "plus"), for: .normal)
button.tintColor = .white
return button
}()
init(viewModel: HeaderViewModelProtocol) {
self.viewModel = viewModel
super.init(frame: .zero)
loadView()
}
func loadView() {
if viewModel.backAction != nil {
backButton.addTarget(self, action: #selector(tapBack), for: .touchUpInside)
addSubview(backButton)
backButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 30).isActive = true
backButton.topAnchor.constraint(equalTo: topAnchor, constant: 36).isActive = true
backButton.widthAnchor.constraint(equalToConstant: 22).isActive = true
backButton.heightAnchor.constraint(equalToConstant: 36).isActive = true
}
if viewModel.helpAction != nil {
helpButton.addTarget(self, action: #selector(tapHelp), for: .touchUpInside)
addSubview(helpButton)
helpButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -30).isActive = true
helpButton.topAnchor.constraint(equalTo: topAnchor, constant: 36).isActive = true
helpButton.widthAnchor.constraint(equalToConstant: 22).isActive = true
helpButton.heightAnchor.constraint(equalToConstant: 36).isActive = true
}
}
@objc func tapBack() {
viewModel.backAction?()
}
@objc func tapHelp() {
viewModel.helpAction?()
}
}
先谢谢大家了!可以联系我哦!
你的评论说你“给headerview高度140”...但是你没有显示如何你正在这样做,所以我仍然认为你的按钮最终超出了视图边界。
这是您的代码,稍作修改:
protocol HeaderViewModelProtocol {
var title: String { get }
var color: UIColor { get }
var imageName: String? { get }
var backAction: (()->Void)? { get set}
var helpAction: (()->Void)? { get set}
}
struct HeaderViewModel: HeaderViewModelProtocol {
let title: String
var color: UIColor = UIColor.white
var imageName: String?
var backAction: (() -> Void)?
var helpAction: (() -> Void)?
}
class HeaderView: UIView {
let viewModel: HeaderViewModelProtocol
private var layer0: CAGradientLayer!
var backButton: UIButton = {
let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
button.addTarget(HeaderView.self, action: #selector(tapBack), for: .touchUpInside)
button.backgroundColor = UIColor.red
button.tag=5
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .clear
button.tintColor = .white
button.setImage(UIImage(named: "back"), for: .normal)
// during development, use a background color so we can easily see the frame
button.backgroundColor = .red
return button
}()
var helpButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .clear
button.setImage(UIImage(named: "plus"), for: .normal)
button.tintColor = .white
// during development, use a background color so we can easily see the frame
button.backgroundColor = .blue
return button
}()
init(viewModel: HeaderViewModelProtocol) {
self.viewModel = viewModel
super.init(frame: .zero)
loadView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func loadView() {
if viewModel.backAction != nil {
backButton.addTarget(self, action: #selector(tapBack), for: .touchUpInside)
addSubview(backButton)
backButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 30).isActive = true
backButton.topAnchor.constraint(equalTo: topAnchor, constant: 36).isActive = true
backButton.widthAnchor.constraint(equalToConstant: 22).isActive = true
backButton.heightAnchor.constraint(equalToConstant: 36).isActive = true
// if you want these UI elements to determine the height
//backButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -36).isActive = true
}
if viewModel.helpAction != nil {
helpButton.addTarget(self, action: #selector(tapHelp), for: .touchUpInside)
addSubview(helpButton)
helpButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -30).isActive = true
helpButton.topAnchor.constraint(equalTo: topAnchor, constant: 36).isActive = true
helpButton.widthAnchor.constraint(equalToConstant: 22).isActive = true
helpButton.heightAnchor.constraint(equalToConstant: 36).isActive = true
// if you want these UI elements to determine the height
//helpButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -36).isActive = true
}
}
@objc func tapBack() {
print("back tapped")
viewModel.backAction?()
}
@objc func tapHelp() {
print("help tapped")
viewModel.helpAction?()
}
}
和一个示例视图控制器来展示它的工作原理:
class HeaderViewVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let headerViewModel = HeaderViewModel(title: "Farmers", helpAction: {
print("Farmers Help Action")
self.navigationController?.popViewController(animated: true) // when debugging this //line doesn't work when adding })
})
let headerView = HeaderView(viewModel: headerViewModel)
headerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(headerView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
headerView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
headerView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
headerView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
headerView.heightAnchor.constraint(equalToConstant: 140.0),
])
// during development... makes it easy to see the view framing
headerView.backgroundColor = .cyan
}
}
运行它,你会看到:
help tapped
Farmers Help Action
点击按钮时输出到调试控制台。
将此代码与您的实际代码进行比较,看看有什么不同。