I created a floating action button which i would like to dismiss all the action button when a user either taps the FAB when it's open or when the user taps anywhere on the screen and FAB is open. It is also important to note that the FAB is being displayed over a tableview and i want to retain the ability to select tableview cells.
In my implementation of the FAB i added a target to the FAB button which i use to open and close the FAB and i also implemented a tapGesture on the viewController with the tableview such that when a tap gesture is invoked i can close the FAB if open.
To make this work i did a bit of research and found out that i have to set
tap.cancelsTouchesInView = false
so that the tableView events continue working. However the side effect is that when i tap on the fab to close it two events are fired one from the tapGesture of the FAB and another from the button target which results in the FAB not closing when u tap on it if its open.
Is there a more elegant way of making the FAB be able to close when tapped whilst its open and also have the tap Gesture on the viewController close the fab when its open and a user taps anywhere on the screen.
Here is some of my code:
ViewController:
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self,
action: #selector(self.dismissActionButtons(_:)))
self.view.addGestureRecognizer(tap)
tap.cancelsTouchesInView = false
self.floatingActionButton.isHidden = true
}
@objc func dismissActionButtons(_ sender: UIButton) {
if !floatingActionButton.actionButtonsCarousel.isHidden {
self.floatingActionButton.animateActionButtonsDisappering()
}
}
Custom FAB View :
override init(frame: CGRect) {
super.init(frame: .zero)
actionButtonsCarousel.isHidden = true
self.translatesAutoresizingMaskIntoConstraints = false
self.mainButton.addTarget(self,
action: #selector(ACTFAB.fabButtonAction(_:)),
for: .touchUpInside)
}
@objc func fabButtonAction(_ sender: UIButton) {
if self.actionButtonsCarousel.isHidden {
self.animateActionButtonsAppering()
} else {
self.animateActionButtonsDisappering()
}
}
func animateActionButtonsAppering() {
self.actionButtonsCarousel.alpha = 0.0
self.actionButtonsCarousel.isHidden = false
UIView.transition(with: self, duration: 0.5, options: .preferredFramesPerSecond60, animations: {
self.actionButtonsCarousel.alpha = 1.0
})
self.mainButton.setImage(UIImage(named: "fab-open-icon"), for: .normal)
}
func animateActionButtonsDisappering() {
self.actionButtonsCarousel.alpha = 1.0
self.actionButtonsCarousel.isHidden = true
UIView.transition(with: self, duration: 0.3, options: .transitionCrossDissolve, animations: {
self.actionButtonsCarousel.alpha = 0.0
})
self.mainButton.setImage(UIImage(named: "fab-closed-icon"), for: .normal)
}
Two valid scenarios:
1 FAB is open -> click FAB -> FAB closes
2 FAB is open -> click anywhere other than FAB -> FAB closes
Scenario number 1 fails with my current code.