UIButton 第一次点击后不可点击

2024-04-07

我试图在单击按钮时从底部引入一个子视图。但只有第一次该按钮是可点击的。动画按钮后第二次单击不可单击。

这是代码。

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")
    } 
}

当屏幕第一次出现时:

Initially the button is clickable and when it is clicked it moves up along with subview. enter image description here

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

但是,如果我将按钮作为子视图放置在 self 内部,而不是作为 mainView 的子视图,则该按钮是可单击的,但即使在视图动画并向上移动后,它仍保持在相同的位置。

self.addSubview(按钮)


所以,我终于得到了我想要在动画前后实现的解决方案。

UIButton 在动画后没有收到任何触摸事件的原因是,动画后,UIButton 向上移动,因为它是 mainView 的子视图。因此,它超出了其 superView 的范围,并且不响应任何单击事件。虽然我移动了按钮及其 superView(即 mainView),但按钮没有响应触摸事件。 然后,我使用 hitTest 测试了按钮绑定是否在 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)

动画后按下按钮时返回 false。

因此,我需要捕获位于其超级视图框架之外的子视图上的触摸事件。

使用 hitTest() 解决了我的问题。 这是对我有帮助的链接。使用 hitTest:withEvent 捕获父视图框架之外的子视图上的触摸: https://stackoverflow.com/questions/11770743/capturing-touches-on-a-subview-outside-the-frame-of-its-superview-using-hittest

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
}

屏幕截图: 当屏幕首次出现时,按钮位于屏幕底部,子视图隐藏在按钮下方。

单击按钮时,mainView 向上动画,并且按钮向上移动,因为它是 mainView 的子视图。

当再次单击按钮时,mainView 会转到之前的位置,按钮也会如此。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UIButton 第一次点击后不可点击 的相关文章

随机推荐