NavigationItem中具有AutoLayout的iOS CustomView没有获得点击

时间:2018-11-21 08:14:00

标签: ios swift uibutton customization uinavigationitem

我为navigationItem创建了一个自定义视图,但是不知何故它没有收到任何点击事件:

customView的代码如下

class CustomNavigationView: UIView {

let backButton: UIButton = {
    let button = UIButton(type: .custom)
    button.setImage(UIImage(named: "icon_back", in: Bundle.main, compatibleWith: nil), for: .normal)
    button.isUserInteractionEnabled = true
    return button
}()

var profileImage: UIImageView = {
    let imageView = UIImageView()
    imageView.image = UIImage(named: "icon_back", in: Bundle.main, compatibleWith: nil)
    return imageView
}()

var profileName: UILabel = {
    let label = UILabel()
    label.text = "No Name"
    label.font = UIFont(name: "HelveticaNeue", size: 16) ?? UIFont.systemFont(ofSize: 16)
    label.textColor = UIColor(red: 96, green: 94, blue: 94)
    return label
}()

var onlineStatusIcon: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor(28, green: 222, blue: 20)
    return view
}()

var onlineStatusText: UILabel = {
    let label = UILabel()
    label.text = "Online"
    label.font = UIFont(name: "HelveticaNeue", size: 12) ?? UIFont.systemFont(ofSize: 12)
    label.textColor = UIColor(red: 113, green: 110, blue: 110)
    return label
}()

lazy var profileView: UIStackView = {
    let stackView = UIStackView(arrangedSubviews: [self.profileName, self.onlineStatusText])
    stackView.alignment = .fill
    stackView.axis = .vertical
    stackView.distribution = .fillEqually
    stackView.spacing = 2
    return stackView
}()

@objc func backButtonClicked(_ sender: UIButton) {
    print("Back Button click successfully")
}

private func setupConstraints() {
    self.addViewsForAutolayout(views: [backButton, profileImage, onlineStatusIcon, profileView])
    //Setup constraints
    backButton.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5).isActive = true
    backButton.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
    backButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10).isActive = true
    backButton.widthAnchor.constraint(equalToConstant: 20).isActive = true

    profileImage.leadingAnchor.constraint(equalTo: backButton.trailingAnchor, constant: 20).isActive = true
    profileImage.topAnchor.constraint(equalTo: self.topAnchor, constant: 5).isActive = true
    profileImage.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -5).isActive = true
    profileImage.widthAnchor.constraint(equalToConstant: 35).isActive = true
    profileImage.layer.cornerRadius = 18
    profileImage.clipsToBounds = true

    onlineStatusIcon.bottomAnchor.constraint(equalTo: profileImage.bottomAnchor, constant: 0).isActive = true
    onlineStatusIcon.leadingAnchor.constraint(equalTo: profileImage.trailingAnchor, constant: -8).isActive = true
    onlineStatusIcon.widthAnchor.constraint(equalToConstant: 10).isActive = true
    onlineStatusIcon.heightAnchor.constraint(equalToConstant: 10).isActive = true
    onlineStatusIcon.layer.cornerRadius = 5
    onlineStatusIcon.clipsToBounds = true

    profileView.leadingAnchor.constraint(equalTo: profileImage.trailingAnchor, constant: 5).isActive = true
    profileView.topAnchor.constraint(equalTo: profileImage.topAnchor).isActive = true
    profileView.bottomAnchor.constraint(equalTo: profileImage.bottomAnchor).isActive = true

}

required init() {
    super.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 40))
    setupConstraints()
    addButtonTarget()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func addButtonTarget() {
    // Setup button callback
    backButton.addTarget(self, action: #selector(backButtonClicked(_:)), for: .touchUpInside)

    print("Target added")
}
}

我将此视图设置为我的视图控制器中的NavigationbarLeft按钮项目:

class ViewController:  UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    let customView = CustomNavigationView()
    self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: customView)
}
}

该视图正确显示,但是单击根本不起作用。 我使用视图调试来检查在此之上是否还有其他层,这可能会引起问题,但这种情况不存在。 使用调试点添加目标时,我还检查了backButton框架。

此问题是否有解决方案?自动布局不适用于导航项中的自定义视图吗?还是我想念的东西。

您可以运行上面的代码,并查看单击是否无效。

这似乎与自动布局有关。如果我对框架位置进行硬编码,则单击将起作用。

class CustomNavigationView: UIView {

let backButton: UIButton = {
    let button = UIButton(frame: CGRect(x: 5, y: 5, width: 30, height: 30))
    button.setImage(UIImage(named: "icon_back", in: Bundle.kommunicate, compatibleWith: nil), for: .normal)
    button.isUserInteractionEnabled = true
    return button
}()

var profileImage: UIImageView = {
    let imageView = UIImageView(frame: CGRect(x: 40, y: 5, width: 30, height: 30))
    imageView.image = UIImage(named: "icon_back", in: Bundle.kommunicate, compatibleWith: nil)
    return imageView
}()

var profileName: UILabel = {
    let label = UILabel(frame: CGRect(x: 80, y: 5, width: 50, height: 15))
    label.text = "No Name"
    label.font = UIFont(name: "HelveticaNeue", size: 16) ?? UIFont.systemFont(ofSize: 16)
    label.textColor = UIColor(red: 96, green: 94, blue: 94)
    return label
}()

var onlineStatusIcon: UIView = {
    let view = UIView(frame: CGRect(x: 65, y: 30, width: 10, height: 10))
    view.backgroundColor = UIColor(28, green: 222, blue: 20)
    return view
}()

var onlineStatusText: UILabel = {
    let label = UILabel(frame: CGRect(x: 80, y: 25, width: 50, height: 10))
    label.text = "Online"
    label.font = UIFont(name: "HelveticaNeue", size: 12) ?? UIFont.systemFont(ofSize: 12)
    label.textColor = UIColor(red: 113, green: 110, blue: 110)
    return label
}()

lazy var profileView: UIStackView = {
    let stackView = UIStackView(arrangedSubviews: [self.profileName, self.onlineStatusText])
    stackView.alignment = .fill
    stackView.axis = .vertical
    stackView.distribution = .fillEqually
    stackView.spacing = 2
    return stackView
}()

@objc func backButtonClicked(_ sender: UIButton) {
    print("Back button is successfully called")
}

private func setupConstraints() {
    self.addSubview(backButton)
    self.addSubview(profileImage)
    self.addSubview(onlineStatusIcon)
    self.addSubview(profileView)
}

required init() {
    super.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 40))
    setupConstraints()
    addButtonTarget()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func addButtonTarget() {
    // Setup button callback
    backButton.addTarget(self, action: #selector(backButtonClicked(_:)), for: .touchUpInside)

    print("Target added")
}
}

1 个答案:

答案 0 :(得分:2)

问题在于您添加的手动添加的约束。 使用视图调试器将CustomNavigationView添加到栏中后的宽度为0

为了强制容器扩展,请在setupConstraints()中添加以下约束:

profileView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true

现在容器可以扩展以匹配其内容,触摸事件应该按预期传播到按钮。