ios - Swift 绘图应用程序很慢

标签 ios swift uiscrollview drawing lag

我目前正在开发一个绘图应用程序。我正在为 iOS 构建它,并使用 Swift 3 来实现。

这只是一个基本的绘图应用程序,但我正在尝试添加一个额外的功能。我从 UIScrollView 开始,然后向该 ScrollView 添加了一个 ImageView 。所有绘图部分都是通过 ImageView 完成的。当您第一次启动应用程序时, ScrollView 会完全放大。当您切换到“缩放模式”时,您可以通过捏合来缩放。问题是,当你第一次打开应用程序时,当你放大绘图时,绘图非常模糊。为了解决这个问题,我可以使用如下代码:

UIGraphicsBeginImageContextWithOptions((self.view.frame.size), false, 7.0)

这会导致绘图在放大时看起来很棒,但会导致应用程序运行非常缓慢。但令我困惑的是,如果我将上面的代码更改为:

UIGraphicsBeginImageContextWithOptions((self.view.frame.size), false, 0.0)

并且一直缩小,绘图看起来完全相同(当然,我一直缩小),但它不再滞后。我知道这可能不是很清楚,所以这里有一个视频显示第一个场景中发生的情况:https://youtu.be/E_9FKf1pUTY第二个:https://youtu.be/OofFTS4Q0OA

所以基本上,我想知道是否有一种方法可以将放大的区域视为它自己的 View 。在我看来,应用程序似乎正在更新整个 ImageView ,而不仅仅是在任何给定时间可见的部分。有没有办法只更新绘制的 ImageView 部分?抱歉,如果这篇文章有点令人困惑,如果有任何不明白的地方,请随时提问。为了清楚起见,我将包含以下所有绘图代码:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    print("Touches began")

    swiped = true

    if let touch = touches.first {
        lastPoint = touch.location(in: scrollView)
        lastPoint.x = lastPoint.x / scrollView.zoomScale
        lastPoint.y = lastPoint.y / scrollView.zoomScale
    }
}

func drawLines(fromPoint:CGPoint,toPoint:CGPoint) {
    print("\(fromPoint.x), \(fromPoint.y)")
    //UIGraphicsBeginImageContext(self.view.frame.size)
    UIGraphicsBeginImageContextWithOptions((scrollView.frame.size), false, 0.0)
    imageView.image?.draw(in: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
    let context = UIGraphicsGetCurrentContext()
    context?.move(to: CGPoint(x: fromPoint.x, y: fromPoint.y))
    context?.addLine(to: CGPoint(x: toPoint.x, y: toPoint.y))

    context?.setBlendMode(CGBlendMode.normal)
    context?.setLineCap(CGLineCap.round)
    if erase == true {
        context?.setLineWidth(30)
    }
    if erase == false {
        context?.setLineWidth(CGFloat(sizeVar))
    }
    if color == "black" {
        context?.setStrokeColor(UIColor.black.cgColor)
    }
    if color == "white" {
        context?.setStrokeColor(UIColor.white.cgColor)
    }
    if color == "blue" {
        context?.setStrokeColor(UIColor.blue.cgColor)
    }
    if color == "cyan" {
        context?.setStrokeColor(UIColor.cyan.cgColor)
    }
    if color == "green" {
        context?.setStrokeColor(UIColor.green.cgColor)
    }
    if color == "magenta" {
        context?.setStrokeColor(UIColor.magenta.cgColor)
    }
    if color == "red" {
        context?.setStrokeColor(UIColor.red.cgColor)
    }
    if color == "yellow" {
        context?.setStrokeColor(UIColor.yellow.cgColor)
    }

    context?.strokePath()

    imageView.image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    swiped = true

    if let touch = touches.first {
        var currentPoint = touch.location(in: scrollView)
        currentPoint.x = currentPoint.x / scrollView.zoomScale
        currentPoint.y = currentPoint.y / scrollView.zoomScale
        drawLines(fromPoint: lastPoint, toPoint: currentPoint)

        lastPoint = currentPoint
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if !swiped {
        drawLines(fromPoint: lastPoint, toPoint: lastPoint)
    }
}

最佳答案

函数 UIGraphicsBeginImageContextWithOptions(_:_:_:) 中的比例参数不是质量设置,您不应在其中放置任意值。它是一个比例因子,类似于图像的 @1x、@2x 和 @3x 设置。它告诉系统将图像像素映射到屏幕像素时要使用的缩放因子。在大多数(几乎所有)情况下,您应该使用 0,这意味着“使用屏幕的原始比例”(@2x 表示正常视网膜,或 @3x 表示 iPhone 6+ 和 7+。)您永远不应该将其设置为任意值例如 7 之类的值。这将创建一个像素数为正常像素数 7 倍的图像,并强制系统每次都对其进行缩放以进行屏幕绘制,这会花费更多时间且速度更慢。

接下来,为每条新线创建一个新图像是一种极其低效的绘图方式。它不断地创建和释放大块内存,然后每次都必须完全重绘屏幕。相反,我会设置一个具有 CAShapeLayer 作为支持层的 View ,并更新安装在该层中的路径。

关于ios - Swift 绘图应用程序很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43728607/

相关文章:

ios - UIScrollView 在 iOS 中使用计时器滑动

ios - Swift 由于内存问题而终止

ios - 无法访问核心数据

ios - Sinch Integration in swift 项目

ios - 将按钮连接到引脚标注

ios - 如何在 UITableView 中显示数组中的 x 个对象,然后在向下滚动时显示更多对象?

ios - 手动滚动由 UIViewPropertyAnimator 动画的 UIScrollView

ios - 快照不起作用?

ios - UICollectionViewCell 中的渐变 BG

objective-c - 使用自动布局的 UIScrollView 内的完全响应式 UIView