How to know that if the only visible area of a .png is touched in Xcode

后端 未结 4 1038
死守一世寂寞
死守一世寂寞 2020-11-30 14:44

I have imported a .png image into UIImageView in Xcode and what I want to make is when the image is touched, it will be hidden.

But my problem is that

相关标签:
4条回答
  • 2020-11-30 14:49

    I have created a custom UIButton subclass that behaves exactly as you describe, have a look: https://github.com/spagosx/iOS-Shaped-Button-Swift

    It's written in Swift, but it's easily convertible to Objective-c.

    The approach is to get the pixel data from the touch point and to access the RGBA values, in this case we read A (alpha) and check if it is higher than our threshold.

    Looking at a bit of code:

    func alphaFromPoint(point: CGPoint) -> CGFloat {
        var pixel: [UInt8] = [0, 0, 0, 0]
        let colourSpace = CGColorSpaceCreateDeviceRGB()
        let alphaInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
        let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colourSpace, bitmapInfo: alphaInfo.rawValue)
    
        context?.translateBy(x: -point.x, y: -point.y)
    
        self.layer.render(in: context!)
    
        let floatAlpha = CGFloat(pixel[3])
        return floatAlpha
    }
    

    You can than take the floatAlpha value and compare it with your acceptable value of alpha:

        override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
            return self.alphaFromPoint(point) >= 100
        }
    
    0 讨论(0)
  • 2020-11-30 14:50

    Combining Danny's and Sport's answer in Swift 4.2 as an extension.

    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
        }
    }
    
    0 讨论(0)
  • 2020-11-30 14:51

    I have taken the liberty of updating 'Danny S's' answer to Swift 5 and removed extraneous code, bug fixed and added some additional clarity to the UX.

    Here's the code:

    https://github.com/ZoeESummers/SOXShapedTapView-Updated.git

    0 讨论(0)
  • 2020-11-30 14:53
      -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
        {
            UITouch *touch = [touches anyObject]; 
            CGPoint touch_point = [touch locationInView:self.view];
    
            if (![imageView pointInside:touch_point withEvent:event]) 
            {
                NSLog(@"you inside imageview");
    // write here what you want
            }
        } 
    
    0 讨论(0)
提交回复
热议问题