iOS CustomView With AutoLayout in navigationItem not receiving clicks
I created a custom view for navigationItem but somehow it is not receiving any click events:
The code for customView is below
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")
}
}
And I am setting this view as NavigationbarLeft button Item in my view Controller:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let customView = CustomNavigationView()
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: customView)
}
}
The view is displaying correctly but the clicks are not working at all.
I used view debugging to check if some other layer is on top of this which might be causing problem but nothing of that sort is present.
I also checked backButton frame when adding the target using debug points.
Is there any solution for this problem. Does autolayout not work with custom view in navigation item? Or is there something that I am missing.
You can run the above piece of code and see that the clicks are not working.
This somehow appears to be related to auto layout. If I hardcode the frame position then clicks are working.
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")
}
}
ios swift uibutton customization uinavigationitem
add a comment |
I created a custom view for navigationItem but somehow it is not receiving any click events:
The code for customView is below
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")
}
}
And I am setting this view as NavigationbarLeft button Item in my view Controller:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let customView = CustomNavigationView()
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: customView)
}
}
The view is displaying correctly but the clicks are not working at all.
I used view debugging to check if some other layer is on top of this which might be causing problem but nothing of that sort is present.
I also checked backButton frame when adding the target using debug points.
Is there any solution for this problem. Does autolayout not work with custom view in navigation item? Or is there something that I am missing.
You can run the above piece of code and see that the clicks are not working.
This somehow appears to be related to auto layout. If I hardcode the frame position then clicks are working.
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")
}
}
ios swift uibutton customization uinavigationitem
you have addded custom view inside leftBarButtonItem so you can not get clicked of button inside custom view
– Jatin Kathrotiya
Nov 21 at 8:52
@JatinKathrotiya I think This is the way you add a customView to a navigationItem. And If you read the question, I have stated it is not working with autolayout. If I try hardcoding frames of every view inside customnavigationView then the click would work.
– Shivam Pokhriyal
Nov 21 at 8:56
Try to addTarget to backButton in your viewController. It would help. But don't ask me why :) Someone else maybe would explain why.
– DennyDog
Nov 21 at 10:08
@DennyDog Tried it, I called addButtonTarget from viewDidLoad of viewController. Still not working. Did you tried yourself?
– shivam pokhriyal
Nov 21 at 11:03
add a comment |
I created a custom view for navigationItem but somehow it is not receiving any click events:
The code for customView is below
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")
}
}
And I am setting this view as NavigationbarLeft button Item in my view Controller:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let customView = CustomNavigationView()
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: customView)
}
}
The view is displaying correctly but the clicks are not working at all.
I used view debugging to check if some other layer is on top of this which might be causing problem but nothing of that sort is present.
I also checked backButton frame when adding the target using debug points.
Is there any solution for this problem. Does autolayout not work with custom view in navigation item? Or is there something that I am missing.
You can run the above piece of code and see that the clicks are not working.
This somehow appears to be related to auto layout. If I hardcode the frame position then clicks are working.
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")
}
}
ios swift uibutton customization uinavigationitem
I created a custom view for navigationItem but somehow it is not receiving any click events:
The code for customView is below
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")
}
}
And I am setting this view as NavigationbarLeft button Item in my view Controller:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let customView = CustomNavigationView()
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: customView)
}
}
The view is displaying correctly but the clicks are not working at all.
I used view debugging to check if some other layer is on top of this which might be causing problem but nothing of that sort is present.
I also checked backButton frame when adding the target using debug points.
Is there any solution for this problem. Does autolayout not work with custom view in navigation item? Or is there something that I am missing.
You can run the above piece of code and see that the clicks are not working.
This somehow appears to be related to auto layout. If I hardcode the frame position then clicks are working.
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")
}
}
ios swift uibutton customization uinavigationitem
ios swift uibutton customization uinavigationitem
edited Nov 21 at 12:29
asked Nov 21 at 8:14
shivam pokhriyal
358
358
you have addded custom view inside leftBarButtonItem so you can not get clicked of button inside custom view
– Jatin Kathrotiya
Nov 21 at 8:52
@JatinKathrotiya I think This is the way you add a customView to a navigationItem. And If you read the question, I have stated it is not working with autolayout. If I try hardcoding frames of every view inside customnavigationView then the click would work.
– Shivam Pokhriyal
Nov 21 at 8:56
Try to addTarget to backButton in your viewController. It would help. But don't ask me why :) Someone else maybe would explain why.
– DennyDog
Nov 21 at 10:08
@DennyDog Tried it, I called addButtonTarget from viewDidLoad of viewController. Still not working. Did you tried yourself?
– shivam pokhriyal
Nov 21 at 11:03
add a comment |
you have addded custom view inside leftBarButtonItem so you can not get clicked of button inside custom view
– Jatin Kathrotiya
Nov 21 at 8:52
@JatinKathrotiya I think This is the way you add a customView to a navigationItem. And If you read the question, I have stated it is not working with autolayout. If I try hardcoding frames of every view inside customnavigationView then the click would work.
– Shivam Pokhriyal
Nov 21 at 8:56
Try to addTarget to backButton in your viewController. It would help. But don't ask me why :) Someone else maybe would explain why.
– DennyDog
Nov 21 at 10:08
@DennyDog Tried it, I called addButtonTarget from viewDidLoad of viewController. Still not working. Did you tried yourself?
– shivam pokhriyal
Nov 21 at 11:03
you have addded custom view inside leftBarButtonItem so you can not get clicked of button inside custom view
– Jatin Kathrotiya
Nov 21 at 8:52
you have addded custom view inside leftBarButtonItem so you can not get clicked of button inside custom view
– Jatin Kathrotiya
Nov 21 at 8:52
@JatinKathrotiya I think This is the way you add a customView to a navigationItem. And If you read the question, I have stated it is not working with autolayout. If I try hardcoding frames of every view inside customnavigationView then the click would work.
– Shivam Pokhriyal
Nov 21 at 8:56
@JatinKathrotiya I think This is the way you add a customView to a navigationItem. And If you read the question, I have stated it is not working with autolayout. If I try hardcoding frames of every view inside customnavigationView then the click would work.
– Shivam Pokhriyal
Nov 21 at 8:56
Try to addTarget to backButton in your viewController. It would help. But don't ask me why :) Someone else maybe would explain why.
– DennyDog
Nov 21 at 10:08
Try to addTarget to backButton in your viewController. It would help. But don't ask me why :) Someone else maybe would explain why.
– DennyDog
Nov 21 at 10:08
@DennyDog Tried it, I called addButtonTarget from viewDidLoad of viewController. Still not working. Did you tried yourself?
– shivam pokhriyal
Nov 21 at 11:03
@DennyDog Tried it, I called addButtonTarget from viewDidLoad of viewController. Still not working. Did you tried yourself?
– shivam pokhriyal
Nov 21 at 11:03
add a comment |
1 Answer
1
active
oldest
votes
The problem is with the manually added constraints that you added.
Using the view debugger the width of CustomNavigationView
after it is added to the bar is 0
.
In order to force the container to expand, add the following constraint in setupConstraints()
:
profileView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
Now that the container expands to match it's contents, the touch events should be propagated to the button as expected.
Thank you so much. I tried view debug myself but missed this.
– shivam pokhriyal
Nov 21 at 13:03
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53407723%2fios-customview-with-autolayout-in-navigationitem-not-receiving-clicks%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The problem is with the manually added constraints that you added.
Using the view debugger the width of CustomNavigationView
after it is added to the bar is 0
.
In order to force the container to expand, add the following constraint in setupConstraints()
:
profileView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
Now that the container expands to match it's contents, the touch events should be propagated to the button as expected.
Thank you so much. I tried view debug myself but missed this.
– shivam pokhriyal
Nov 21 at 13:03
add a comment |
The problem is with the manually added constraints that you added.
Using the view debugger the width of CustomNavigationView
after it is added to the bar is 0
.
In order to force the container to expand, add the following constraint in setupConstraints()
:
profileView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
Now that the container expands to match it's contents, the touch events should be propagated to the button as expected.
Thank you so much. I tried view debug myself but missed this.
– shivam pokhriyal
Nov 21 at 13:03
add a comment |
The problem is with the manually added constraints that you added.
Using the view debugger the width of CustomNavigationView
after it is added to the bar is 0
.
In order to force the container to expand, add the following constraint in setupConstraints()
:
profileView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
Now that the container expands to match it's contents, the touch events should be propagated to the button as expected.
The problem is with the manually added constraints that you added.
Using the view debugger the width of CustomNavigationView
after it is added to the bar is 0
.
In order to force the container to expand, add the following constraint in setupConstraints()
:
profileView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
Now that the container expands to match it's contents, the touch events should be propagated to the button as expected.
edited Nov 21 at 13:57
answered Nov 21 at 12:54
Aris
1,293613
1,293613
Thank you so much. I tried view debug myself but missed this.
– shivam pokhriyal
Nov 21 at 13:03
add a comment |
Thank you so much. I tried view debug myself but missed this.
– shivam pokhriyal
Nov 21 at 13:03
Thank you so much. I tried view debug myself but missed this.
– shivam pokhriyal
Nov 21 at 13:03
Thank you so much. I tried view debug myself but missed this.
– shivam pokhriyal
Nov 21 at 13:03
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53407723%2fios-customview-with-autolayout-in-navigationitem-not-receiving-clicks%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
you have addded custom view inside leftBarButtonItem so you can not get clicked of button inside custom view
– Jatin Kathrotiya
Nov 21 at 8:52
@JatinKathrotiya I think This is the way you add a customView to a navigationItem. And If you read the question, I have stated it is not working with autolayout. If I try hardcoding frames of every view inside customnavigationView then the click would work.
– Shivam Pokhriyal
Nov 21 at 8:56
Try to addTarget to backButton in your viewController. It would help. But don't ask me why :) Someone else maybe would explain why.
– DennyDog
Nov 21 at 10:08
@DennyDog Tried it, I called addButtonTarget from viewDidLoad of viewController. Still not working. Did you tried yourself?
– shivam pokhriyal
Nov 21 at 11:03