Ios 为什么在以下场景中,贝塞尔路径内的hitTest/tap检测会产生不准确的结果?

Ios 为什么在以下场景中,贝塞尔路径内的hitTest/tap检测会产生不准确的结果?,ios,swift,xcode,uibezierpath,paintcode,Ios,Swift,Xcode,Uibezierpath,Paintcode,我需要在我的UI的一个非常特定的区域内检测敲击声-一个角度的钢琴键,这里用蓝色突出显示,但我目前设置的方式,检测不准确: 因为这不是一个简单的矩形,我不能只使用一个普通的按钮。相反,我决定使用PaintCode插件直接从草图创建贝塞尔路径 在你说这个问题是重复的之前:是的,我知道,事实上我非常依赖Abhimanyu Rathore和Diogo Souza的答案来实现基本功能 草图图像由三部分组成,blackKeyTop、blackKeySide和blackKeyBottom,这就是为什么Pai

我需要在我的UI的一个非常特定的区域内检测敲击声-一个角度的钢琴键,这里用蓝色突出显示,但我目前设置的方式,检测不准确:

因为这不是一个简单的矩形,我不能只使用一个普通的按钮。相反,我决定使用
PaintCode
插件
直接从
草图
创建贝塞尔路径

在你说这个问题是重复的之前:是的,我知道,事实上我非常依赖Abhimanyu Rathore和Diogo Souza的答案来实现基本功能

草图图像由三部分组成,
blackKeyTop
blackKeySide
blackKeyBottom
,这就是为什么PaintCode似乎创建了三个单独的bezier路径:

//
//  StyleKit.swift
//
//  Created on May 2, 2019.
//
//  Generated by PaintCode Plugin for Sketch
//  http://www.paintcodeapp.com/sketch
//

import UIKit

var currentBezierPath = UIBezierPath()

class StyleKit: NSObject {

    //MARK: - Canvas Drawings

    /// Page 1

    class func drawA5(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 200, height: 516), resizing: ResizingBehavior = .aspectFit) {
        /// General Declarations
        let context = UIGraphicsGetCurrentContext()!
        let baseTransform = context.userSpaceToDeviceSpaceTransform.inverted()

        /// Resize to Target Frame
        context.saveGState()
        let resizedFrame = resizing.apply(rect: CGRect(x: 0, y: 0, width: 200, height: 516), target: targetFrame)
        context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY)
        context.scaleBy(x: resizedFrame.width / 200, y: resizedFrame.height / 516)

        /// A#5 highlight
        do {
            context.saveGState()
            context.translateBy(x: 96.5, y: 260)
            context.scaleBy(x: -1, y: 1)
            context.translateBy(x: -87.5, y: -250)

            /// black key bottom
            let blackKeyBottom = UIBezierPath()
            blackKeyBottom.move(to: CGPoint(x: 66.43, y: 85.19))
            blackKeyBottom.addCurve(to: CGPoint(x: 72.75, y: 85.19), controlPoint1: CGPoint(x: 70.35, y: 85.49), controlPoint2: CGPoint(x: 72.46, y: 85.49))
            blackKeyBottom.addCurve(to: CGPoint(x: 72.04, y: 81.34), controlPoint1: CGPoint(x: 73.04, y: 84.89), controlPoint2: CGPoint(x: 72.8, y: 83.61))
            blackKeyBottom.addLine(to: CGPoint(x: 58.18, y: 21.72))
            blackKeyBottom.addCurve(to: CGPoint(x: 49.42, y: 7.99), controlPoint1: CGPoint(x: 54.67, y: 14.84), controlPoint2: CGPoint(x: 51.75, y: 10.26))
            blackKeyBottom.addCurve(to: CGPoint(x: 28.57, y: 0), controlPoint1: CGPoint(x: 43.73, y: 2.43), controlPoint2: CGPoint(x: 36.47, y: 0))
            blackKeyBottom.addCurve(to: CGPoint(x: 7.87, y: 8.55), controlPoint1: CGPoint(x: 20.59, y: 0), controlPoint2: CGPoint(x: 13.33, y: 3))
            blackKeyBottom.addCurve(to: CGPoint(x: 0, y: 21.2), controlPoint1: CGPoint(x: 5.71, y: 10.76), controlPoint2: CGPoint(x: 3.08, y: 14.97))
            blackKeyBottom.addLine(to: CGPoint(x: 1.33, y: 81.34))
            blackKeyBottom.addLine(to: CGPoint(x: 1.33, y: 85.66))
            blackKeyBottom.addLine(to: CGPoint(x: 4.33, y: 85.66))
            blackKeyBottom.addLine(to: CGPoint(x: 66.43, y: 85.19))
            blackKeyBottom.close()
            context.saveGState()
            context.translateBy(x: 2.09, y: 411.53)
            // Warning: Blur effects are not supported.
            blackKeyBottom.usesEvenOddFillRule = true
            context.saveGState()
            context.beginPath()
            context.addPath(blackKeyBottom.cgPath)
            context.addRect(blackKeyBottom.bounds.insetBy(dx: -74, dy: -74))
            context.clip(using: .evenOdd)
            context.translateBy(x: -147.87, y: 0)
            do {
                let baseZero = context.convertToDeviceSpace(CGPoint.zero).applying(baseTransform)
                let baseOne = context.convertToDeviceSpace(CGPoint(x: 1, y: 1)).applying(baseTransform)
                let baseOffset = context.convertToDeviceSpace(CGPoint(x: 147.87, y: 0)).applying(baseTransform)
                let shadowOffset = CGSize(width: baseOffset.x - baseZero.x, height: baseOffset.y - baseZero.y)
                let shadowBlur: CGFloat = 74 * min(baseOne.x - baseZero.x, baseOne.y - baseZero.y)
                context.setShadow(offset: shadowOffset, blur: shadowBlur, color: UIColor(hue: 0.616, saturation: 1, brightness: 1, alpha: 0.5).cgColor)
            }
            UIColor.black.setFill()
            blackKeyBottom.fill()
            context.restoreGState()
            blackKeyBottom.usesEvenOddFillRule = true
            UIColor(white: 0.847, alpha: 1).setFill()
            blackKeyBottom.fill()
            UIColor(hue: 0.622, saturation: 0.975, brightness: 0.831, alpha: 1).setFill()
            blackKeyBottom.fill()
            context.restoreGState()

            currentBezierPath.append(blackKeyBottom)

            /// black key side
            let blackKeySide = UIBezierPath()
            blackKeySide.move(to: CGPoint(x: 14.38, y: 498.36))
            blackKeySide.addLine(to: CGPoint(x: 15.36, y: 495.31))
            blackKeySide.addLine(to: CGPoint(x: 28.85, y: 422.78))
            blackKeySide.addLine(to: CGPoint(x: 111.37, y: 33.73))
            blackKeySide.addLine(to: CGPoint(x: 89.45, y: 0))
            blackKeySide.addLine(to: CGPoint(x: 11.65, y: 358.27))
            blackKeySide.addLine(to: CGPoint(x: 0.91, y: 408.5))
            blackKeySide.addLine(to: CGPoint(x: 0, y: 415.52))
            blackKeySide.addLine(to: CGPoint(x: 0.54, y: 422.78))
            blackKeySide.addLine(to: CGPoint(x: 5.44, y: 457.06))
            blackKeySide.addLine(to: CGPoint(x: 11.65, y: 492.02))
            blackKeySide.addLine(to: CGPoint(x: 14.38, y: 498.36))
            blackKeySide.close()
            context.saveGState()
            context.translateBy(x: 63.02, y: 1.09)
            // Warning: Blur effects are not supported.
            blackKeySide.usesEvenOddFillRule = true
            context.saveGState()
            context.beginPath()
            context.addPath(blackKeySide.cgPath)
            context.addRect(blackKeySide.bounds.insetBy(dx: -74, dy: -74))
            context.clip(using: .evenOdd)
            context.translateBy(x: -186.37, y: 0)
            do {
                let baseZero = context.convertToDeviceSpace(CGPoint.zero).applying(baseTransform)
                let baseOne = context.convertToDeviceSpace(CGPoint(x: 1, y: 1)).applying(baseTransform)
                let baseOffset = context.convertToDeviceSpace(CGPoint(x: 186.37, y: 0)).applying(baseTransform)
                let shadowOffset = CGSize(width: baseOffset.x - baseZero.x, height: baseOffset.y - baseZero.y)
                let shadowBlur: CGFloat = 74 * min(baseOne.x - baseZero.x, baseOne.y - baseZero.y)
                context.setShadow(offset: shadowOffset, blur: shadowBlur, color: UIColor(hue: 0.616, saturation: 1, brightness: 1, alpha: 0.5).cgColor)
            }
            UIColor.black.setFill()
            blackKeySide.fill()
            context.restoreGState()
            blackKeySide.usesEvenOddFillRule = true
            UIColor(hue: 0.622, saturation: 1, brightness: 0.745, alpha: 0.77).setFill()
            blackKeySide.fill()
            context.restoreGState()

            currentBezierPath.append(blackKeySide)

            /// black key top
            let blackKeyTop = UIBezierPath()
            blackKeyTop.move(to: CGPoint(x: 8.55, y: 376.64))
            blackKeyTop.addLine(to: CGPoint(x: 1.08, y: 409.47))
            blackKeyTop.addLine(to: CGPoint(x: 0, y: 425.43))
            blackKeyTop.addLine(to: CGPoint(x: 0.6, y: 437.48))
            blackKeyTop.addCurve(to: CGPoint(x: 6.37, y: 421.98), controlPoint1: CGPoint(x: 1.3, y: 431.07), controlPoint2: CGPoint(x: 3.22, y: 425.91))
            blackKeyTop.addCurve(to: CGPoint(x: 13.55, y: 415.73), controlPoint1: CGPoint(x: 7.95, y: 420.01), controlPoint2: CGPoint(x: 10.34, y: 417.93))
            blackKeyTop.addCurve(to: CGPoint(x: 18.28, y: 412.98), controlPoint1: CGPoint(x: 15.71, y: 414.18), controlPoint2: CGPoint(x: 17.29, y: 413.26))
            blackKeyTop.addCurve(to: CGPoint(x: 23.32, y: 411.58), controlPoint1: CGPoint(x: 19.27, y: 412.7), controlPoint2: CGPoint(x: 20.96, y: 412.23))
            blackKeyTop.addLine(to: CGPoint(x: 30.23, y: 410.75))
            blackKeyTop.addLine(to: CGPoint(x: 37.04, y: 411.58))
            blackKeyTop.addLine(to: CGPoint(x: 44.39, y: 414.18))
            blackKeyTop.addLine(to: CGPoint(x: 52.05, y: 419.89))
            blackKeyTop.addLine(to: CGPoint(x: 57.52, y: 428.52))
            blackKeyTop.addLine(to: CGPoint(x: 65.5, y: 451.2))
            blackKeyTop.addLine(to: CGPoint(x: 62.73, y: 420.81))
            blackKeyTop.addLine(to: CGPoint(x: 63.2, y: 408.02))
            blackKeyTop.addLine(to: CGPoint(x: 65.7, y: 396.36))
            blackKeyTop.addLine(to: CGPoint(x: 151.29, y: 3.88))
            blackKeyTop.addCurve(to: CGPoint(x: 151.73, y: 0.61), controlPoint1: CGPoint(x: 151.69, y: 1.96), controlPoint2: CGPoint(x: 151.84, y: 0.87))
            blackKeyTop.addCurve(to: CGPoint(x: 149.11, y: 0), controlPoint1: CGPoint(x: 151.62, y: 0.35), controlPoint2: CGPoint(x: 150.75, y: 0.14))
            blackKeyTop.addLine(to: CGPoint(x: 101.04, y: 0))
            blackKeyTop.addCurve(to: CGPoint(x: 98.87, y: 2.39), controlPoint1: CGPoint(x: 100.09, y: 0.38), controlPoint2: CGPoint(x: 99.37, y: 1.18))
            blackKeyTop.addCurve(to: CGPoint(x: 96.96, y: 9.3), controlPoint1: CGPoint(x: 98.38, y: 3.6), controlPoint2: CGPoint(x: 97.74, y: 5.9))
            blackKeyTop.addLine(to: CGPoint(x: 8.55, y: 376.64))
            blackKeyTop.close()
            context.saveGState()
            context.translateBy(x: 0.96, y: 0.84)
            // Warning: Blur effects are not supported.
            blackKeyTop.usesEvenOddFillRule = true
            context.saveGState()
            context.beginPath()
            context.addPath(blackKeyTop.cgPath)
            context.addRect(blackKeyTop.bounds.insetBy(dx: -55, dy: -55))
            context.clip(using: .evenOdd)
            context.translateBy(x: -247.76, y: 0)
            do {
                let baseZero = context.convertToDeviceSpace(CGPoint.zero).applying(baseTransform)
                let baseOne = context.convertToDeviceSpace(CGPoint(x: 1, y: 1)).applying(baseTransform)
                let baseOffset = context.convertToDeviceSpace(CGPoint(x: 247.76, y: 0)).applying(baseTransform)
                let shadowOffset = CGSize(width: baseOffset.x - baseZero.x, height: baseOffset.y - baseZero.y)
                let shadowBlur: CGFloat = 15 * min(baseOne.x - baseZero.x, baseOne.y - baseZero.y)
                context.setShadow(offset: shadowOffset, blur: shadowBlur, color: UIColor(hue: 0.622, saturation: 1, brightness: 0.714, alpha: 0.5).cgColor)
            }
            context.beginTransparencyLayer(auxiliaryInfo: nil)
            do {
                UIColor.black.setFill()
                blackKeyTop.fill()
                context.saveGState()
                blackKeyTop.lineWidth = 8
                UIColor.black.setStroke()
                blackKeyTop.stroke()
                context.restoreGState()
            }
            context.endTransparencyLayer()
            context.restoreGState()
            blackKeyTop.usesEvenOddFillRule = true
            UIColor(white: 1, alpha: 0.8).setFill()
            blackKeyTop.fill()
            UIColor(hue: 0.616, saturation: 1, brightness: 1, alpha: 0.72).setFill()
            blackKeyTop.fill()
            context.restoreGState()

            currentBezierPath.append(blackKeyTop)

            context.restoreGState()
        }

        context.restoreGState()
    }


    //MARK: - Canvas Images

    /// Page 1

    class func imageOfA5() -> UIImage {
        struct LocalCache {
            static var image: UIImage!
        }
        if LocalCache.image != nil {
            return LocalCache.image
        }
        var image: UIImage

        UIGraphicsBeginImageContextWithOptions(CGSize(width: 200, height: 516), false, 0)
        StyleKit.drawA5()
        image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        LocalCache.image = image
        return image
    }


    //MARK: - Resizing Behavior

    enum ResizingBehavior {
        case aspectFit /// The content is proportionally resized to fit into the target rectangle.
        case aspectFill /// The content is proportionally resized to completely fill the target rectangle.
        case stretch /// The content is stretched to match the entire target rectangle.
        case center /// The content is centered in the target rectangle, but it is NOT resized.

        func apply(rect: CGRect, target: CGRect) -> CGRect {
            if rect == target || target == CGRect.zero {
                return rect
            }

            var scales = CGSize.zero
            scales.width = abs(target.width / rect.width)
            scales.height = abs(target.height / rect.height)

            switch self {
                case .aspectFit:
                    scales.width = min(scales.width, scales.height)
                    scales.height = scales.width
                case .aspectFill:
                    scales.width = max(scales.width, scales.height)
                    scales.height = scales.width
                case .stretch:
                    break
                case .center:
                    scales.width = 1
                    scales.height = 1
            }

            var result = rect.standardized
            result.size.width *= scales.width
            result.size.height *= scales.height
            result.origin.x = target.minX + (target.width - result.width) / 2
            result.origin.y = target.minY + (target.height - result.height) / 2
            return result
        }
    }


}
如您所见,我添加了一个变量currentBezierPath,并将黑键绘图的3个独立部分附加到它上(因为我希望能够检测黑键上的任何位置,而不仅仅是顶部)

然后,我在一个单独的.swift文件中创建了一个自定义类,其占位符名称来自paintcode(目前):

import UIKit

@IBDesignable
class FromPaintCode: UIView {

    override func draw(_ rect: CGRect) {
        StyleKit.drawA5(frame: self.bounds)
    }

    //MARK:- Hit TAP
    @objc public func tapDetected(tapRecognizer: UITapGestureRecognizer) {
        let tapLocation: CGPoint = tapRecognizer.location(in: self)
        self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))
    }

    func hitTest(tapLocation: CGPoint) {
        let path: UIBezierPath = currentBezierPath

        if path.contains(tapLocation) {
            print("tap inside bezier path detected!")
        } else {
            print("tap outside bezier path detected!")
        }
    }

}
。。。然后,我将一个简单的
UIView
连接到主ViewController中名为“
aSharp5ViewOutlet
”的插座,并在
viewDidLoad()中添加一个
UIAPTgestureRecognitor

问题是,目前的点击识别不准确:黑色(蓝色)键的底部似乎始终返回成功的点击,但顶部和侧面似乎有斑点,在键的中间,我收到“检测到bezier路径外的点击!”消息。此外,我还得到了错误的“检测到贝塞尔路径内的点击!”稍微偏外,在键的右侧

我尝试过这样做,但没有添加/附加贝塞尔路径(例如,只关注键的顶部),但也有同样的问题

关于如何解决这个问题有什么建议吗

编辑:

我决定选择一条更简单的路线,用简单的矩形(UIButtons)来近似钢琴键,并以一定角度旋转以匹配图像中的角度。有点像这样:

let testTransform = CGAffineTransform(rotationAngle: .pi * 0.93)

testButton.transform = testTransform

亲爱的@Matvey您在以下方面做得很好:-

  • 从paintcode
  • 获取名为
    ui视图
  • UIViewController
    上从paintcode
  • 添加
    
    
  • 在paintcode
  • 中的视图
    上添加
    uitappesturerecognizer
    我想的问题是
    :-

    1。我们在视图中添加所有内容的函数中的StyleKit计算:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    override func draw(rect:CGRect){
    StyleKit.drawA5(框架:self.bounds)
    }

    2。ui我们从故事板创建的视图。

    2解决方案可以是:-

    解决方案1:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    1。首先,我们将在
    UIViewController
    :-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    2。在您的
    UIViewController
    中添加全局
    currentBezierPath
    :-
    var currentBezierPath=UIBezierPath

    然后,我们将在这个
    **testView**
    中使用currentBezierPath绘制一个简单的CAShapeLayer:-

    currentBezierPath = UIBezierPath(ovalInRect: testView.bounds)
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = currentBezierPath.CGPath
    shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).CGColor
    shapeLayer.strokeColor = UIColor.blackColor().CGColor
    shapeLayer.lineWidth = 2.0
    testView.layer.addSublayer(shapeLayer)
    
    private func hitTest(tapLocation:CGPoint){
        let path:UIBezierPath = self.currentBezierPath
    
        if path.contains(tapLocation){
            //tap detected do what ever you want ..;)
        }else{
            //ooops you taped on other position in view
        }}
    
  • 在此测试视图上添加手势:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    testView.addGestureRecognizer(tapRecognizer)

  • 4.在
    UIViewController
    中注册点击功能:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    5。在没有StyleKit帮助的情况下,尝试使用简单样式的命中测试进行单路径测试:-

    currentBezierPath = UIBezierPath(ovalInRect: testView.bounds)
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = currentBezierPath.CGPath
    shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).CGColor
    shapeLayer.strokeColor = UIColor.blackColor().CGColor
    shapeLayer.lineWidth = 2.0
    testView.layer.addSublayer(shapeLayer)
    
    private func hitTest(tapLocation:CGPoint){
        let path:UIBezierPath = self.currentBezierPath
    
        if path.contains(tapLocation){
            //tap detected do what ever you want ..;)
        }else{
            //ooops you taped on other position in view
        }}
    
    重要信息:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    如果上面的练习可以提高准确性,那么我们需要查看StyleKit,并通过将UIGraphicsGetCurrentContext替换为CAShapeLayer来编辑它,因为层添加到UIView上,并由UIAPTgestureRecognitor inside view正确检测

    解决方案2:-

    在您的上下文中,只需在UIViewController中使用简单的触摸事件即可

    与您分享问题和解决方案:-


    亲爱的@Matvey您在以下方面做得很好:-

  • 从paintcode
  • 获取名为
    ui视图
  • UIViewController
    上从paintcode
  • 添加
    
    
  • 在paintcode
  • 中的视图
    上添加
    uitappesturerecognizer
    我想的问题是
    :-

    1。我们在视图中添加所有内容的函数中的StyleKit计算:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    override func draw(rect:CGRect){
    StyleKit.drawA5(框架:self.bounds)
    }

    2。ui我们从故事板创建的视图。

    2解决方案可以是:-

    解决方案1:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    1。首先,我们将在
    UIViewController
    :-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    2。在您的
    UIViewController
    中添加全局
    currentBezierPath
    :-
    var currentBezierPath=UIBezierPath

    然后,我们将在这个
    **testView**
    中使用currentBezierPath绘制一个简单的CAShapeLayer:-

    currentBezierPath = UIBezierPath(ovalInRect: testView.bounds)
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = currentBezierPath.CGPath
    shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).CGColor
    shapeLayer.strokeColor = UIColor.blackColor().CGColor
    shapeLayer.lineWidth = 2.0
    testView.layer.addSublayer(shapeLayer)
    
    private func hitTest(tapLocation:CGPoint){
        let path:UIBezierPath = self.currentBezierPath
    
        if path.contains(tapLocation){
            //tap detected do what ever you want ..;)
        }else{
            //ooops you taped on other position in view
        }}
    
  • 在此测试视图上添加手势:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    testView.addGestureRecognizer(tapRecognizer)

  • 4.在
    UIViewController
    中注册点击功能:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    5。在没有StyleKit帮助的情况下,尝试使用简单样式的命中测试进行单路径测试:-

    currentBezierPath = UIBezierPath(ovalInRect: testView.bounds)
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = currentBezierPath.CGPath
    shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).CGColor
    shapeLayer.strokeColor = UIColor.blackColor().CGColor
    shapeLayer.lineWidth = 2.0
    testView.layer.addSublayer(shapeLayer)
    
    private func hitTest(tapLocation:CGPoint){
        let path:UIBezierPath = self.currentBezierPath
    
        if path.contains(tapLocation){
            //tap detected do what ever you want ..;)
        }else{
            //ooops you taped on other position in view
        }}
    
    重要信息:-

      let testView = UIView()
        testView.frame = CGRect.init(x: 0, y: 0, width: 300, height: 300)
        testView.backgroundColor = .red
        testView.center = self.view.center
        self.view.addSubview(testView.center)
    
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.tapDetected(tapRecognizer:)))
    
    public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: testView)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))}
    
    如果上面的练习能够提高准确性,那么我们需要查看StyleKit并通过将UIGraphicsGetCurrentContext替换为