Я создал кнопку с плавающим действием, которую я хотел бы отменить всеми кнопками действия, когда пользователь либо нажимает FAB, когда он открыт, либо когда пользователь нажимает в любом месте экрана, и FAB открыт. Также важно отметить, что FAB отображается поверх табличного представления, и я хочу сохранить возможность выбора ячеек табличного представления.
В моей реализации FAB я добавил цель к кнопке FAB, которую я использую, чтобы открывать и закрывать FAB, и я также реализовал tapGesture в viewController с табличным представлением так, чтобы при вызове жеста касания яможно открыть FAB, если он открыт.
Чтобы сделать эту работу, я провел небольшое исследование и обнаружил, что мне нужно установить
tap.cancelsTouchesInView = false
, чтобы tableViewСобытия продолжают работать. Однако побочным эффектом является то, что когда я нажимаю на фабрику, чтобы закрыть ее, запускаются два события - одно из tapGesture FAB, а другое - из кнопки-назначения, что приводит к тому, что FAB не закрывается, когда ты нажимаешь на него, если он открыт.
Существует ли более элегантный способ сделать так, чтобы FAB мог закрываться при касании, когда он открыт, а также иметь жест «Касание» в viewController, чтобы закрыть фабрику, когда он открыт, и пользователь нажимает в любом месте экрана.
Вот мой код:
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()
}
}
Пользовательский 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)
}
Два допустимых сценария:
1 FAB открыт -> нажмите FAB -> FAB закрывается
2 FAB открыт -> нажмите в любом месте, кроме FAB -> FAB закрывается
Сценарий № 1 не соответствует моему текущему коду.