自定义形状可触摸区域

时间:2015-10-05 07:55:40

标签: ios swift uibutton hittest

我的形状如下所示,我希望将其设置为我的UIButton 的背景,但可触摸区域是一个矩形, 是否有任何建议要改变可触摸区域来塑造寄宿生?

enter image description here

3 个答案:

答案 0 :(得分:2)

我们的想法是拥有一个UIButton的子类来覆盖以下方法:

func hitTest(_ point: CGPoint,
   withEvent event: UIEvent?) -> UIView? // that's for handling the case of multiple custom subviews on your view rather than for evaluating if it's your view to handle the touch

func pointInside(_ point: CGPoint,
       withEvent event: UIEvent?) -> Bool // way more preferable than hit test in your case!!!

Objective-C中有一个使用命中测试的教程(只是为了捕捉这个想法)。在您的情况下,最难的问题是检测接收的触摸位置是否在您的自定义形状的范围内(上面的教程依赖于像素透明度,而不是您的情况)。我假设你使用Bezier路径绘制形状。如果这就是您所做的,您可以使用UIBezierPath的func containsPoint(_ point: CGPoint) -> Bool实现评估中的点。祝好运。 P.S.关于UIBezierPath还有一个棘手的问题:

  

如果一个点在里面,则不认为该点被路径包围   一个开放的子路径,无论该区域是否被绘制   在填充操作期间。因此,确定打开时的鼠标命中   路径,您必须创建路径对象的副本并显式关闭   调用此方法之前的任何子路径(使用closePath方法)。

答案 1 :(得分:0)

实际上我发现它就像这样并且工作得很好:

How to know that if the only visible area of a .png is touched in XCode (swift or objective C)

必须更改以下代码:

   func alphaFromPoint(point: CGPoint) -> CGFloat {
   var pixel: [UInt8] = [0, 0, 0, 0]
   let colorSpace = CGColorSpaceCreateDeviceRGB();
   let alphaInfo : CGBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)
   let context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, colorSpace, alphaInfo.rawValue) //need add .rawValue to alphaInfo

   CGContextTranslateCTM(context, -point.x, -point.y);

   self.layer.renderInContext(context!)

   let floatAlpha = CGFloat(pixel[3])
   return floatAlpha

}

答案 2 :(得分:0)

雨燕4.2

最好为UIButton编写一个扩展。覆盖touchesBegan功能,并检查触摸区域是否透明。

extension UIButton{

    open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = event!.touches(for: self)?.first {
            let location = touch.location(in: self)
            if alphaFromPoint(point: location) == 0 {
                self.cancelTracking(with: nil)
                print("cancelled!")
            } else{
                super.touchesBegan(touches, with: event)
            }
        }
    }

    func alphaFromPoint(point: CGPoint) -> CGFloat {
        var pixel: [UInt8] = [0, 0, 0, 0]
        let colorSpace = CGColorSpaceCreateDeviceRGB();
        let alphaInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
        let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: alphaInfo.rawValue)

        context!.translateBy(x: -point.x, y: -point.y)
        self.layer.render(in: context!)

        let floatAlpha = CGFloat(pixel[3])
        return floatAlpha
    }
}