Reputation: 411
All I want to do is rotating the UIBarButtonItem when it is clicked.
I followed this post Rotate UIBarButtonItem Swift, but it is not working.
The difference is:
1- I set the image on runtime when view is loaded:
showHideBtn.image = showHeaderimage
2- I have two buttons in my right Bar button items:
Here is my code:
@IBAction func rotateAction(_ sender: Any) {
if(!self.isVertical)
{
UIView.animate(withDuration: 0.2, animations: {
self.navigationItem.rightBarButtonItem?.customView?.transform = CGAffineTransform(rotationAngle: 90 * .pi / 180)
}, completion: { (finished) in
self.isVertical = true
})
}else{
UIView.animate(withDuration: 0.2, animations: {
self.navigationItem.rightBarButtonItem?.customView?.transform = CGAffineTransform.identity
}, completion: { (finished) in
self.isVertical = false
})
}
}
What am I doing wrong?
Updated code:
DispatchQueue.main.async {
if(!self.isVertical) {
UIView.animate(withDuration: 0.2, animations: {
self.navigationItem.rightBarButtonItem?.customView?.transform = CGAffineTransform(rotationAngle: 90 * .pi / 180)
}, completion: { (finished) in
self.isVertical = true
})
}else {
UIView.animate(withDuration: 0.2, animations: {
self.navigationItem.rightBarButtonItem?.customView?.transform = CGAffineTransform(rotationAngle: 90 * .pi / 180)
}, completion: { (finished) in
self.isVertical = false
})
} }
Show button property:
Upvotes: 1
Views: 1693
Reputation: 452
It could be how you've set the custom view in the bar item. Maybe this self.navigationItem.rightBarButtonItem?.customView?.
is returning nil. Anyway, here is a working version:
Creating the custom UIBarButtonItem:
let button1: UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 60, height: 30))
let button2: UIButton = UIButton(frame: CGRect(x: 70, y: 0, width: 60, height: 30))
override func viewDidLoad(_ animated: Bool) {
super.viewDidLoad(animated)
button1.backgroundColor = .gray
button1.setTitle("CustomButton", for: .normal)
button1.addTarget(self, action: #selector(rotateAction(_:)), for: .touchUpInside)
let barItem1: UIBarButtonItem = UIBarButtonItem(customView: button1)
button2.backgroundColor = .gray
button2.setTitle("CustomButton", for: .normal)
button2.addTarget(self, action: #selector(rotateAction(_:)), for: .touchUpInside)
let barItem2: UIBarButtonItem = UIBarButtonItem(customView: button1)
navigationItem.setRightBarButtonItems([barItem1, barItem2], animated: true)
}
Animate the tapped button:
@objc func rotateAction(_ sender: UIButton) {
let customView = sender
let transform: CGAffineTransform = isVertical ? .identity : CGAffineTransform(rotationAngle: 90 * .pi / 180)
UIView.animate(withDuration: 0.2, animations: {
customView.transform = transform
}, completion: { (finished) in
self.isVertical = !self.isVertical
})
}
To avoid replacing the bar button item/items set from storyboard, get those button items and create an array of bar button item including those with the ones you created in code:
let existingBarItems: [UIBarButtonItem] = navigationItem.rightBarButtonItems ?? []
let rightBarItems = existingBarItems = [yourCustomButtonItem]
navigationItem.setRightBarButtonItems(rightBarItems, animated: true)
And make sure your custom bar button item's frame doesn't intersect with existing buttons.
Upvotes: 2