首页 > 解决方案 > 为视图实现 UIPanGestureRecognizer 时,触摸绘图不起作用

问题描述

我有屏幕来测试带有弹出气泡的设备触摸屏。并且为它们添加了一些由交叉组成的气泡的子视图中的 imageView。然后用户在气泡上滑动以检查触摸屏。

我想在同一个视图上绘图。当用户在气泡上滑动手指时,将绘制一条线。我有单独的绘图类并将其分配给控制器的主父视图。

如果我删除 UIPanGestureRecognizer 的代码,那么绘图工作并且没有滞后。如果我添加手势来查看像这样弹出气泡

view.addGestureRecognizer(gestureRecognizer)

然后有一个滞后,绘图不起作用。

我想要两个东西,比如弹出气泡和在视图中绘图。这个手势的主要问题是当我在视图中添加它时,绘图工作没有任何延迟,但弹出气泡不起作用。

    let gestureRecognizer : UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureRecognized(_:)))

            gestureRecognizer.maximumNumberOfTouches = 1
            gestureRecognizer.minimumNumberOfTouches = 1


            view.addGestureRecognizer(gestureRecognizer)

图纸视图类

    import UIKit

    class DrawingView: UIView {

        var drawColor = UIColor.black
        var lineWidth: CGFloat = 5

        private var lastPoint: CGPoint!
        private var bezierPath: UIBezierPath!
        private var pointCounter: Int = 0
        private let pointLimit: Int = 128
        private var preRenderImage: UIImage!

        // MARK: - Initialization

        override init(frame: CGRect) {
            super.init(frame: frame)

            initBezierPath()
        }

        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)

            initBezierPath()
        }

        func initBezierPath() {
            bezierPath = UIBezierPath()
            bezierPath.lineCapStyle = CGLineCap.round
            bezierPath.lineJoinStyle = CGLineJoin.round
        }

        // MARK: - Touch handling

        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            let touch: AnyObject? = touches.first
            lastPoint = touch!.location(in: self)
            pointCounter = 0
        }

        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
            let touch: AnyObject? = touches.first
            let newPoint = touch!.location(in: self)

            bezierPath.move(to: lastPoint)
            bezierPath.addLine(to: newPoint)
            lastPoint = newPoint

            pointCounter += 1

            if pointCounter == pointLimit {
                pointCounter = 0
                renderToImage()
                setNeedsDisplay()
                bezierPath.removeAllPoints()
            }
            else {
                setNeedsDisplay()
            }
        }

        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            pointCounter = 0
            renderToImage()
            setNeedsDisplay()
            bezierPath.removeAllPoints()
        }

        override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
            touchesEnded(touches!, with: event)
        }

        // MARK: - Pre render

        func renderToImage() {

            UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0)
            if preRenderImage != nil {
                preRenderImage.draw(in: self.bounds)
            }

            bezierPath.lineWidth = lineWidth
            drawColor.setFill()
            drawColor.setStroke()
            bezierPath.stroke()

            preRenderImage = UIGraphicsGetImageFromCurrentImageContext()

            UIGraphicsEndImageContext()
        }

        // MARK: - Render

        override func draw(_ rect: CGRect) {
            super.draw(rect)

            if preRenderImage != nil {
                preRenderImage.draw(in: self.bounds)
            }

            bezierPath.lineWidth = lineWidth
            drawColor.setFill()
            drawColor.setStroke()
            bezierPath.stroke()
        }

        // MARK: - Clearing

        func clear() {
            preRenderImage = nil
            bezierPath.removeAllPoints()
            setNeedsDisplay()
        }

        // MARK: - Other

        func hasLines() -> Bool {
            return preRenderImage != nil || !bezierPath.isEmpty
        }

    }

标签: iosswiftviewuipangesturerecognizer

解决方案


推荐阅读