我创建了一个 float 操作按钮,当用户在 FAB 打开时点击它,或者当用户点击屏幕上的任意位置并且 FAB 打开时,我想关闭所有操作按钮。同样重要的是要注意 FAB 显示在 tableview 上,我想保留选择 tableview 单元格的能力。
在我的 FAB 实现中,我向 FAB 按钮添加了一个目标,我用它来打开和关闭 FAB,我还在 viewController 上使用 tableview 实现了一个 tapGesture,这样当调用一个点击手势时,我可以关闭如果打开 FAB。
为了完成这项工作,我做了一些研究,发现我必须设置
tap.cancelsTouchesInView = false
以便 tableView 事件继续工作。然而,副作用是,当我点击 fab 关闭它时,会触发两个事件,一个是从 FAB 的 tapGesture 触发,另一个是从按钮目标触发,这导致 FAB 在打开时点击它时不会关闭。
有没有一种更优雅的方法可以让 FAB 在打开时被点击关闭,并且当它打开并且用户点击屏幕上的任意位置时,viewController 上的点击手势也可以关闭 fab。
这是我的一些代码:
View Controller :
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 is open -> click FAB -> FAB closes
2 FAB is open -> click anywhere other than FAB -> FAB closes
场景 1 因我当前的代码而失败。
最佳答案
如果我正确理解你的问题,问题是点击 FAB 会导致按钮的 Action 被触发,而且当你将事件传递给底层 viewController 时,gestureRecogniser 也会触发。
我假设按钮操作是主要事件,并且当它触发时您需要停止 gestureRecogniser。 gestureRecogniser 有一个 .location(in:)
方法,它允许您根据任何 View 获取第一个点击位置(对于 tapGestureRecogniser),而 UIView
有一个.point(inside: with:)
方法检查 CGPoint
(根据它自己的坐标空间)是否在它的边界内。因此你应该能够做这样的事情(从内存而不是编译,所以可能需要一些调整但希望它能让你开始):
@objc func dismissActionButtons(_ sender: UIButton) {
let tapPoint = sender.location(in: customFABview)
if customFABview.point(inside: tapPoint, with: nil) &&
!floatingActionButton.actionButtonsCarousel.isHidden {
self.floatingActionButton.animateActionButtonsDisappering()
}
}
关于ios - 如何隐藏 View 的 subview ( float 操作按钮)以防止点击两个不同的区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58798105/