Swift - 如何使 UIButton 仅在附加图像上点击交互并忽略透明部分
Swift - How to make UIButton tap Interaction only on the image attached and ignore transparent parts
我正在创建具有不同图像形状的按钮...一切正常,但如果创建了一个菱形,您可以单击按钮的透明部分。我设法设置了阴影以尊重按钮的形状,因此它看起来突出显示但我如何应用它以便在与之交互时忽略按钮的透明部分?
我找到了一些答案,但我没有使用路径来创建 UIButton 形状,而是使用 UIButton 上的图像。
下面是如何创建我的按钮之一并设置发光
extension UIbutton {
func createSquareButton(buttonPositionX: CGFloat, buttonPositionY: CGFloat, buttonWidth: CGFloat, buttonHeight: CGFloat, buttonTitle: String) {
let button = self
button.isUserInteractionEnabled = true
button.frame = CGRect(x: buttonPositionX, y: buttonPositionY, width: buttonWidth, height: buttonHeight)
button.setTitle(buttonTitle, for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.setTitleColor(UIColor.black, for: .highlighted)
button.alpha = 1.0
button.titleLabel?.font = .systemFont(ofSize: 20)
button.backgroundColor = nil
button.tintColor = Style.PurpleColor
let image = UIImage(named: "Plain Square")
let imageView = UIImageView(image: image)
imageView.setImageColor(color: Style.PurpleColor)
button.setBackgroundImage(imageView.image, for: .normal)
button.setBackgroundImage(imageView.image, for: .selected)
button.setBackgroundImage(imageView.image, for: .highlighted)
}
}
func buttonGlow(sender: CustomBtn){
for button in buttonArray {
if button.UUIDtag == currentSelectedMarkerUUID {
sender.layer.shadowColor = button.tintColor.cgColor
sender.layer.shadowRadius = 15
sender.layer.shadowOpacity = 1.0
sender.layer.masksToBounds = false
} else {
let otherBtn = tmpButtonPicked(uuid: button.UUIDtag!)
otherBtn.layer.shadowColor = UIColor.clear.cgColor
otherBtn.layer.shadowRadius = 0
}
}
}
extension UIImageView {
func setImageColor(color: UIColor) {
let templateImage = self.image?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
self.image = templateImage
self.tintColor = color
}
}
感谢 Malik 的帮助,我解决了这个问题。
首先您需要实现下面的函数,它可以识别您在按钮中点击的位置的 alpha 值。
func alphaFromPoint(sender: CustomBtn, 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)
sender.layer.render(in: context!)
let floatAlpha = CGFloat(pixel[3])
return floatAlpha
}
然后我调整了@IBaction 以接收事件类型。然后我将 Malik 提到的代码添加到 @IBaction
@IBAction func mainButton(sender: CustomBtn, forEvent event: UIEvent){
let touches = event.touches(for: sender)
let touch = touches?.first
guard let touchPoint = touch?.location(in: sender) else {return}
let alphaValue = alphaFromPoint(sender: sender, point: touchPoint)
if alphaValue > 0 {
//Do Something if the alpha value is bigger than 0
}
}
如果从 alphaValue 变量返回的值为 0,那么您就知道它是透明的。
Swift 5 版本 alphaFromPoint
函数。
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
}
我正在创建具有不同图像形状的按钮...一切正常,但如果创建了一个菱形,您可以单击按钮的透明部分。我设法设置了阴影以尊重按钮的形状,因此它看起来突出显示但我如何应用它以便在与之交互时忽略按钮的透明部分?
我找到了一些答案,但我没有使用路径来创建 UIButton 形状,而是使用 UIButton 上的图像。
下面是如何创建我的按钮之一并设置发光
extension UIbutton {
func createSquareButton(buttonPositionX: CGFloat, buttonPositionY: CGFloat, buttonWidth: CGFloat, buttonHeight: CGFloat, buttonTitle: String) {
let button = self
button.isUserInteractionEnabled = true
button.frame = CGRect(x: buttonPositionX, y: buttonPositionY, width: buttonWidth, height: buttonHeight)
button.setTitle(buttonTitle, for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.setTitleColor(UIColor.black, for: .highlighted)
button.alpha = 1.0
button.titleLabel?.font = .systemFont(ofSize: 20)
button.backgroundColor = nil
button.tintColor = Style.PurpleColor
let image = UIImage(named: "Plain Square")
let imageView = UIImageView(image: image)
imageView.setImageColor(color: Style.PurpleColor)
button.setBackgroundImage(imageView.image, for: .normal)
button.setBackgroundImage(imageView.image, for: .selected)
button.setBackgroundImage(imageView.image, for: .highlighted)
}
}
func buttonGlow(sender: CustomBtn){
for button in buttonArray {
if button.UUIDtag == currentSelectedMarkerUUID {
sender.layer.shadowColor = button.tintColor.cgColor
sender.layer.shadowRadius = 15
sender.layer.shadowOpacity = 1.0
sender.layer.masksToBounds = false
} else {
let otherBtn = tmpButtonPicked(uuid: button.UUIDtag!)
otherBtn.layer.shadowColor = UIColor.clear.cgColor
otherBtn.layer.shadowRadius = 0
}
}
}
extension UIImageView {
func setImageColor(color: UIColor) {
let templateImage = self.image?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
self.image = templateImage
self.tintColor = color
}
}
感谢 Malik 的帮助,我解决了这个问题。
首先您需要实现下面的函数,它可以识别您在按钮中点击的位置的 alpha 值。
func alphaFromPoint(sender: CustomBtn, 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)
sender.layer.render(in: context!)
let floatAlpha = CGFloat(pixel[3])
return floatAlpha
}
然后我调整了@IBaction 以接收事件类型。然后我将 Malik 提到的代码添加到 @IBaction
@IBAction func mainButton(sender: CustomBtn, forEvent event: UIEvent){
let touches = event.touches(for: sender)
let touch = touches?.first
guard let touchPoint = touch?.location(in: sender) else {return}
let alphaValue = alphaFromPoint(sender: sender, point: touchPoint)
if alphaValue > 0 {
//Do Something if the alpha value is bigger than 0
}
}
如果从 alphaValue 变量返回的值为 0,那么您就知道它是透明的。
Swift 5 版本 alphaFromPoint
函数。
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
}