第一次点击后,UIButton不可点击

我试图从button被点击时从底部带来一个子视图。 但只有第一次button是可点击的。 在animationbutton不可点击后再次点击。

这是代码。

class AnimateView: UIView { var button: UIButton! var menuView: UIView! var mainView: UIView! override init(frame: CGRect) { super.init(frame: frame) mainView = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)) mainView.clipsToBounds = true mainView.backgroundColor = .clear mainView.isUserInteractionEnabled = true mainView.isExclusiveTouch = true self.addSubview(mainView) let theRect = CGRect(x: self.frame.size.width / 2 - 44 / 2, y: 0, width: 44, height: 44) button = UIButton(frame: theRect) check.layer.cornerRadius = btnView.frame.size.height / 2 mainView.addSubview(self.check) mainView.bringSubview(toFront: check) check.addTarget(self, action: #selector(buttonClick(_:)), for:.touchUpInside) let newRect = CGRect(x: 0, y: check.frame.height, width: self.frame.size.width, height: self.mainView.frame.size.height) menuView = UIView(frame: newRect) menuView.backgroundColor = .blue mainView.addSubview(menuView) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func buttonClick(_ sender: UIButton) { toggleMenu() } func toggleMenu() { if check.transform == CGAffineTransform.identity { UIView.animate(withDuration: 1, animations: { self.check.transform = CGAffineTransform(scaleX: 12, y: 12) self.mainView.transform = CGAffineTransform(translationX: 0, y: -120) self.check.transform = CGAffineTransform(rotationAngle: self.radians(180)) // 180 is 3.14 radian self.setNeedsLayout() }) { (true) in UIView.animate(withDuration: 0.5, animations: { }) } } else { UIView.animate(withDuration: 1, animations: { // .identity sets to original position //self.btnView.transform = .identity self.mainView.transform = .identity self.button.transform = .identity }) } } } 

这个类是从另一个UIView类调用的

 class MainViewClass: UIView { var animateView: AnimateView! override init(frame: CGRect) { animateView = AnimateView(frame: CGRect(x: 0, y: self.frame.size.height - 44 - 44 - 20, width: self.frame.size.width, height: 122+44)) //animateView.clipsToBounds = true self.addSubview(animateView) self.bringSubview(toFront: animateView) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 

当屏幕第一次出现时:

在这里输入图像说明

最初button是可点击的,当它被点击时,它随子视图一起向上移动。 在这里输入图像说明

现在该button不可点击。 当我看到button的框架时,它与屏幕最初出现时的相同,即使button触摸屏幕底部,即使它向上移动。 我想要的是当点击button时从底部显示带有animation的屏幕,并且第二次点击移动到默认位置。

但是,如果我把button作为子视图放在自己的内部,而不是作为mainView的子视图,那么button是可点击的,但即使在视图被animation和向上移动之后,它仍保持在相同的位置。

self.addSubview(button)

在这里输入图像说明

所以,我最终得到了animation之前和之后我打算实现的解决scheme。

UIButton在animation之后没有收到任何触摸事件的原因是animation之后,UIButton向上移动,因为它是mainView的子视图。 由于这个原因,它超出了它的superView的界限,并且不响应任何点击事件。 虽然我移动了它的主视图superView,但button没有响应触摸事件。 然后,我使用hitTesttesting了button绑定是否在mainView中:

 override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let pointForTargetView: CGPoint = button.convert(point, from: mainView) if button.bounds.contains(pointForTargetView) { print("Button pressed") return button.hitTest(pointForTargetView, with:event) } return super.hitTest(point, with: event) } 

这个如果条件:

button.bounds.contains(pointForTargetView)

在animation之后按下button时返回false。

所以,我需要捕获超级视图框外的子视图上的触摸事件。

使用hitTest()解决了我的问题。 这是帮助我的链接。 使用hitTest:withEvent捕获超级视图框架外部的子视图:

Swift 3

 override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if clipsToBounds || isHidden || alpha == 0 { return nil } for subview in subviews.reversed() { let subPoint = subview.convert(point, from: self) if let result = subview.hitTest(subPoint, with: event) { return result } } return nil } 

屏幕截图:当屏幕第一次出现时,button位于屏幕底部,子视图隐藏在button下方。

在这里输入图像说明

当点击button时,mainView向上animation,button向上移动,因为它是mainView的子视图。

在这里输入图像说明

当再次点击button时,mainView也会转到上一个位置,button也是如此。

在这里输入图像说明