【发布时间】:2015-03-11 11:21:31
【问题描述】:
我已经在 Xcode 中将一个 .png 图像导入到UIImageView,我想做的是当图像被触摸时,它将被隐藏。
但我的问题是 png 图像包含透明部分,当我触摸透明部分时,动作会继续。我希望仅在触摸图像的可见部分时才进行操作。如何解决问题?
Swift 或 Objective-C
【问题讨论】:
标签: ios objective-c swift uiimageview
我已经在 Xcode 中将一个 .png 图像导入到UIImageView,我想做的是当图像被触摸时,它将被隐藏。
但我的问题是 png 图像包含透明部分,当我触摸透明部分时,动作会继续。我希望仅在触摸图像的可见部分时才进行操作。如何解决问题?
Swift 或 Objective-C
【问题讨论】:
标签: ios objective-c swift uiimageview
我创建了一个自定义 UIButton 子类,它的行为与您描述的完全一样,看看:https://github.com/spagosx/iOS-Shaped-Button-Swift
它是用 Swift 编写的,但很容易转换为 Objective-c。
方法是从触摸点获取像素数据并访问 RGBA 值,在这种情况下,我们读取 A (alpha) 并检查它是否高于我们的阈值。
看一点代码:
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
}
您可以将 floatAlpha 值与您可接受的 alpha 值进行比较:
override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
return self.alphaFromPoint(point) >= 100
}
【讨论】:
let alphaInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue) let context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, colorSpace, alphaInfo.rawValue)
我冒昧地更新了“Danny S”对 Swift 5 的回答并删除了无关代码、修复了错误并为用户体验增加了一些额外的清晰度。
代码如下:
【讨论】:
-(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
}
}
【讨论】:
在 Swift 4.2 中结合 Danny 和 Sport 的答案作为扩展。
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
}
}
【讨论】: