How to Know That If the Only Visible Area of a .Png Is Touched in Xcode

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

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
}

How to check whether a CGPoint is inside a UIImageView?

Sounds to me like the problem is you need to convert coordinates from your view's coordinates to the UIImageView's coordinates. You can use UIView's convertPoint method.

Try replacing

if ([image pointInside:touch_point withEvent:event]) {

with

if ([image pointInside: [self.view convertPoint:touch_point toView: image] withEvent:event]) {

(Note that you are allowed to pass nil instead of event.)

I guess this is a bit late for the questioner, but I hope it is of use to someone.

Custom shape touchable area

Actually I found it on this like and working perfectly:

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

But must change code like below:

   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

}

Detect if a layer that uses a transform contains a touch point

I found an alternate solution. SpaceDog got me thinking about the situation differently. I just need to know if an area with color is touched. I found this post and translated it to Objective C. It works beautifully. While I would prefer the detection of the point was within the arrow, this should work for my purposes just as well. Thanks for y'all's reply. I appreciate it.

Post I got the code below from.

- (void) tapped: (UITapGestureRecognizer *) sender {
CGPoint location = [sender locationInView: sender.view];
CGFloat p = [self alphaFromPoint:location];
if (p > 0) {
[_delegate arrowTouched:self];
}
}

- (CGFloat) alphaFromPoint: (CGPoint) point {
UInt8 pixel[4] = {0,0,0,0};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo alphaInfo = (CGBitmapInfo)kCGImageAlphaPremultipliedLast;

CGContextRef context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, colorSpace, alphaInfo);

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

[self.layer renderInContext:context];
CGFloat floatAlpha = pixel[3];
return floatAlpha;
}

How to invoke method on click on only visible part of animage view

Have a look at github for the OBSHAPED button .it will resolve your problem Happy coding.:)

How to make the frame of a button custom shape in Swift 2

Here is an example of a button that only responds to touches within a certain area.

Sample Image

class MyButton: UIButton {

var path: UIBezierPath!

override func awakeFromNib() {
backgroundColor = UIColor.greenColor()
addTarget(self, action: #selector(touchDown), forControlEvents: .TouchDown)
}
override func drawRect(rect: CGRect) {
path = UIBezierPath()

path.moveToPoint(CGPointMake(150, 10))
path.addLineToPoint(CGPointMake(200, 10))
path.addLineToPoint(CGPointMake(150, 100))
path.addLineToPoint(CGPointMake(100, 100))
path.closePath()

let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = UIColor.redColor().CGColor
shapeLayer.fillColor = UIColor.blueColor().CGColor
shapeLayer.path = path.CGPath
layer.addSublayer(shapeLayer)

}

func touchDown(button: MyButton, event: UIEvent) {
if let touch = event.touchesForView(button)?.first {
let location = touch.locationInView(button)

if path.containsPoint(location) == false {
button.cancelTrackingWithEvent(nil)
}
}

}
}


Related Topics



Leave a reply



Submit