首页 > 解决方案 > UIButton 失去响应(即无法按下它),可能是因为 CGAffineTransform

问题描述

首先,我认为问题出在 上UIVisualEffectView,但现在我认为问题出在CGAffineTransform我用来为openOptionsTooltip()


首先,我在该问题上发现了一个类似的问题(请参阅已接受答案的评论),但在我的情况下,我将按钮添加为 的子视图,而UIVisualEffectView不是将其添加为按钮子视图。

苹果文档说:

根据所需的效果,效果可能会影响视图后面的分层内容或添加到视觉效果视图的 contentView 的内容。

但是我找不到更好的解释来解释它如何或为什么会影响添加到 contentView 的内容。

这是我的代码:

创建视图的方法:

    func createOptionsTooltip(withNamesAndActions options: [(name: String , action: Selector)]){

        self.tooltipSize = CGSize(width: 250, height: CGFloat(60*options.count+12))
        var optionItens : [UIView] = []
        for i in 0..<options.count{
            let optionView = UIView(frame: CGRect(x: .zero, y: CGFloat(60*i), width: self.tooltipSize.width, height: 60))
            optionView.backgroundColor = .clear

            let separatorView = UIView(frame: CGRect(x: .zero, y: 59, width: self.tooltipSize.width, height: 1))
            separatorView.backgroundColor = UIColor(white: 0.8, alpha: 0.5)
            let button = UIButton(frame: CGRect(x: .zero, y: .zero, width: self.tooltipSize.width, height: 59))
            button.setTitle(options[i].name, for: .normal)
            button.setTitleColor(self.view.tintColor, for: .normal)
            button.addTarget(self, action: options[i].action, for: .touchUpInside)
            button.isEnabled = true
            button.isUserInteractionEnabled = true

            optionView.addSubview(button)
            optionView.addSubview(separatorView)
            optionView.bringSubviewToFront(button)

            optionItens.append(optionView)
        }


        self.blackOpaqueView = UIView(frame: self.view.bounds)
        self.blackOpaqueView.backgroundColor = UIColor.black
        self.blackOpaqueView.alpha = 0
        let gesture = UITapGestureRecognizer(target: self, action: #selector(ScheduleNavigationController.closeOptionsTooltip))
//        blackOpaqueView.addGestureRecognizer(gesture)

        self.vwTooltip = UIView(frame: CGRect(origin: CGPoint(x: self.view.frame.midX - self.tooltipSize.width/2, y: self.view.frame.minY+self.navigationBar.frame.size.height+UIApplication.shared.statusBarFrame.height+10), size: CGSize(width: 1, height: 1)))
        self.vwTooltip.transform = self.vwTooltip.transform.scaledBy(x: 1, y: 0.01)
        self.vwTooltip.isHidden = true

        let vwAim = UIVisualEffectView(frame: CGRect(x: self.tooltipSize.width/2 - 6, y: 0, width: 12, height: 10))
        let vwBalloon = UIVisualEffectView(frame: CGRect(x: 0, y: vwAim.frame.size.height, width: self.tooltipSize.width, height: CGFloat(60*options.count)))
        vwBalloon.cornerRadius = 8
        vwBalloon.contentView.isUserInteractionEnabled = true
        vwBalloon.isUserInteractionEnabled = true

        let bezPath = trianglePathWithCenter(rect: vwAim.frame)

        let maskForPath = CAShapeLayer()
        maskForPath.path = bezPath.cgPath
        vwAim.layer.mask = maskForPath


        vwBalloon.effect = UIBlurEffect(style: .prominent)
        vwAim.effect = UIBlurEffect(style: .prominent)

        for optionView in optionItens{
            vwBalloon.contentView.addSubview(optionView)
            vwBalloon.bringSubviewToFront(optionView)
        }
        self.vwTooltip.addSubview(vwBalloon)
        self.vwTooltip.addSubview(vwAim)
        self.vwTooltip.bringSubviewToFront(vwBalloon)
        vwBalloon.bringSubviewToFront(vwBalloon.contentView)


    }

我不是在viewDidLoad那个路上打电话的:

createOptionsTooltip(withNamesAndActions: [("Sair", #selector(ScheduleNavigationController.closeSchedule(_:))), ("Hoje", #selector(ScheduleNavigationController.scrollToToday(_:)))])

我以这种方式打开动画工具提示:

func openOptionsTooltip(){
    if let appDelegate = UIApplication.shared.delegate as? AppDelegate{

        appDelegate.window?.addSubview(blackOpaqueView)
        appDelegate.window?.addSubview(vwTooltip)
        appDelegate.window?.bringSubviewToFront(vwTooltip)

        UIView.animate(withDuration: 0.2, animations: {
            self.blackOpaqueView.alpha = 0.5
        }) { _ in
            self.vwTooltip.isHidden = false
            UIView.animate(withDuration: 0.1, animations: {
                self.vwTooltip.transform = self.vwTooltip.transform.scaledBy(x: 1, y: 100)
            })
        }
    }
}

我试过的:

PS:我发现UIVisualEffectView有 3 个子视图,但显然 contentView 是上面的视图,请参阅打印它的子视图的日志:

    ▿ 3 elements
  - 0 : <_UIVisualEffectBackdropView: 0x102dcd140; frame = (0 0; 250 120); autoresize = W+H; userInteractionEnabled = NO; layer = <UICABackdropLayer: 0x280d1b480>>
  - 1 : <_UIVisualEffectSubview: 0x102dcd350; frame = (0 0; 250 120); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x280d15c80>>
  - 2 : <_UIVisualEffectContentView: 0x102dcc940; frame = (0 0; 250 120); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x280d1ace0>>

我不知道是什么阻止了按钮的用户交互

结果如下:

标签: iosswift

解决方案


我发现了问题:

在调用openOptionsTooltip()内部的转换后,它并没有调整所有子视图的大小,但它vwTooltp本身并没有改变它的框架,但是因为它的clipToBounds属性是假的,所以所有的子视图都显示出来了,但是用户不能访问按钮动作,因为视图尺寸为 1x1。将方法更改为openOptionsTooltip()

func openOptionsTooltip(){
        if let appDelegate = UIApplication.shared.delegate as? AppDelegate{

            appDelegate.window?.addSubview(blackOpaqueView)
            appDelegate.window?.addSubview(vwTooltip)
            appDelegate.window?.bringSubviewToFront(vwTooltip)


             UIView.animate(withDuration: 0.2, delay: 0.0, options: UIView.AnimationOptions.allowUserInteraction, animations:{
                self.blackOpaqueView.alpha = 0.5
            }) { _ in
                self.vwTooltip.isHidden = false
                 UIView.animate(withDuration: 0.1, delay: 0.0, options: UIView.AnimationOptions.allowUserInteraction, animations:{
                    self.vwTooltip.transform = self.vwTooltip.transform.translatedBy(x: 1, y: 1)
                    self.vwTooltip.transform = self.vwTooltip.transform.scaledBy(x: 1, y: 100)
                 }){ _ in
                    self.vwTooltip.frame = self.tooltipFrame
                }
            }
        }
    }

现在它工作正常。感谢您的回复


推荐阅读