只制作png可点击部分的UI按钮swift

时间:2016-07-12 22:48:23

标签: ios swift png

嗨我有一个文件,其中视图由10个分层图像构成,这些图像是具有大透明部分的png。我喜欢这个只能在可见部分上点击,但我怎么试试它只是注册点击的顶部图像/按钮。我尝试过UI按钮和可点击的UIImage视图。我在swift 2.2工作。有没有人知道如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

  1. 按视图层次结构中的z位置对图像视图进行排序。当多个不透明区域重叠时,这可以确保正确的行为。
  2. 遍历所有图片。
  3. 对于每个图像,检查所选位置处像素的alpha分量。
  4. alpha将介于某个范围之间(通常介于0 ... 100之间)。如果alpha值大于某个阈值量,则响应点击并退出,否则检查下一张图像。
  5. 下面是一个如何工作的例子。界面构建器中添加了图像和点按手势。此示例只是将点击视图放在前面,尽管可以根据您的需要轻松修改它。

    class ClickViewController: UIViewController {
    
        @IBOutlet var images: [UIImageView]!
    
        @IBAction internal func tapGestureHandler(gesture: UITapGestureRecognizer) {
    
            let sorted = images.sort() { a, b in
                return a.layer.zPosition < b.layer.zPosition
            }
    
            for (i, image) in sorted.enumerate() {
    
                let location = gesture.locationInView(image)
                let alpha = image.alphaAtPoint(location)
    
                if alpha > 50.0 {
    
                    print("selected image #\(i) \(image.layer.zPosition)")
                    view.addSubview(image)
    
                    return
                }
            }
        }
    }
    

    以下是如何设置故事板的示例。请注意图像视图和点击手势识别器。也可以以编程方式添加视图。

    Views and gesture recogniser

    将每张图片链接到连接检查器引用插座集合下的images IBCollection。

    Images added to the IBCollection

    以下是在抽头位置确定图像中像素的alpha分量的代码。下面的代码是作为另一个similar question on SO的答案提供的。

    extension UIImageView {
    
        //
        // Return the alpha component of a pixel in the UIImageView.
        //
        // See: https://stackoverflow.com/questions/27923232/how-to-know-that-if-the-only-visible-area-of-a-png-is-touched-in-xcode-swift-o?rq=1
        //
        func alphaAtPoint(point: CGPoint) -> CGFloat {
    
            var pixel: [UInt8] = [0, 0, 0, 0]
            let colorSpace = CGColorSpaceCreateDeviceRGB();
            let alphaInfo = CGImageAlphaInfo.PremultipliedLast.rawValue
    
            guard let context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, colorSpace, alphaInfo) else {
                return 0
            }
    
            CGContextTranslateCTM(context, -point.x, -point.y);
    
            layer.renderInContext(context)
    
            let floatAlpha = CGFloat(pixel[3])
    
            return floatAlpha
        }
    }
    

    请参阅example app available on GitHub

答案 1 :(得分:0)

@Luke Van In 谢谢你的回答,它给了我很多帮助。

以下是Swift 3版本:(某些语法更改)

import UIKit

class ViewController: UIViewController {

@IBOutlet var images: [UIImageView]!

@IBAction internal func tapGestureHandler(gesture: UITapGestureRecognizer) {

    let sorted = images.sorted() { a, b in
        return a.layer.zPosition < b.layer.zPosition
    }

    for (i, image) in sorted.enumerated() {

        let location = gesture.location(in: image)
        let alpha = image.alphaAtPoint(point: location)

        if alpha > 50.0 {

            print("selected image #\(i) \(image.layer.zPosition)")
            view.addSubview(image)

            return
        }
    }
}



}

extension UIImageView {

func alphaAtPoint(point: CGPoint) -> CGFloat {

    var pixel: [UInt8] = [0, 0, 0, 0]
    let colorSpace = CGColorSpaceCreateDeviceRGB();
    let alphaInfo = CGImageAlphaInfo.premultipliedLast.rawValue

    guard let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: alphaInfo) else {
        return 0
    }

    context.translateBy(x: -point.x, y: -point.y);

    layer.render(in: context)

    let floatAlpha = CGFloat(pixel[3])

    return floatAlpha
 }
}