关于ios:iOS-开发简单的手绘应用

50次阅读

共计 2995 个字符,预计需要花费 8 分钟才能阅读完成。

开发一款简略的 iOS 手绘利用,

收集点,绘制形态,给形态着色,出现给用户,如同就完了

框架是 Quartz2D

1,收集点

首先须要有一个界面 UIView, 用这个界面监听用户的手势,收集点

  • 用户按下手指

location(in, 从触摸事件中,取得在画板中的坐标


var lastPoint = CGPoint.zero


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else {return}
    // ...
    lastPoint = touch.location(in: view)
  }
  • 用户挪动手指
 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {//  ...}
  • 用户抬起手指

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

2, 绘制形态,给形态着色

开拓一块绘图上下文 UIGraphicsGetCurrentContext,

应用采集的点连线

用户手绘的不是一段间断的曲线,是很多个线段拼接起来的


func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) {UIGraphicsBeginImageContext(view.frame.size)
   guard let context = UIGraphicsGetCurrentContext() else {return}
   // ...
   // 绘制
   context.move(to: fromPoint)
   context.addLine(to: toPoint)
   
   context.setLineCap(.round)
   context.setBlendMode(.normal)
   context.setLineWidth(brushWidth)
   context.setStrokeColor(color.cgColor)
   
   context.strokePath()
   // ...
   
   UIGraphicsEndImageContext()}

3, 出现给用户

第一步应用的 UIView 是 UIImageView,

  • 绘制就是画一小段,取出画好的图片,赋给 UIImageView,咱们就看到了
  • 间断的绘制,是

画一小段,取出画好的图片,赋给 UIImageView,并用变量保留下最新的图片

接着画,先把方才的图片变量绘制一遍,再画一小段,取出画好的图片,赋给 UIImageView,并用变量保留下最新的图片

func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) {UIGraphicsBeginImageContext(view.frame.size)
  guard let context = UIGraphicsGetCurrentContext() else {return}
  tempImageView.image?.draw(in: view.bounds)
  
  // 绘制 ...
  
  tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
  
  UIGraphicsEndImageContext()}

4, 画笔设置

批改画笔色彩和粗细
func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) {UIGraphicsBeginImageContext(view.frame.size)
  guard let context = UIGraphicsGetCurrentContext() else {return}
  
  // ...
  
  context.setBlendMode(.normal)
  
  // 调色彩
  context.setLineWidth(brushWidth)
  // 调粗细
   context.setStrokeColor(color.cgColor)
  // ...
}

画笔变橡皮擦

  • 办法一,把画笔的色彩,调成画板的色彩,就成了橡皮擦
  • 办法 2,

把画笔的色彩,调成通明,

把绘图上下文的混色模式改掉

就成了橡皮擦

       switch type {
       case .pencil, .none:
           context.setBlendMode(.color)
       case .eraser:
           context.setLineWidth(15)
           context.setStrokeColor(UIColor.clear.cgColor)
           context.setBlendMode(.clear)
       }

5,后续

更多功能:

退出文本输出性能,

须要一个文本框控件 UITextFieldUITextView

文本框控件个别能够拖动,

文本框放在画布上,拖出画布了,有些问题。

这时候要做一个边界检测

性能优化:

个别性能优化,就是打印函数的执行工夫

当画布的大小为 1366 X 7700(iPad Pro + UIScrollView ) 的时候,画布很大,

全副绘制一遍,并取出图片,性能耗费很大

    tempImageView.image?.draw(in: view.bounds)
    // ...
    
    tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()

绘制一次,须要约 0.07 秒,

 let t = Date()
 self.drawingImage()
 if #available(iOS 13.0, *) {let span = t.distance(to: Date())
     print(span)
 }

咱们冀望 60 的 FPS, 每一帧计算工夫 0.016, 所以频繁调用该办法,卡得厉害


之前的办法是一个点,一个点的绘制

挪动一下,绘制一次


 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else {return}
    swiped = true
    let currentPoint = touch.location(in: view)
    drawLine(from: lastPoint, to: currentPoint)
    lastPoint = currentPoint
    }

画一段线,func touchesMoved(),个别能够触发 30 ~ 60 次,收集的点比拟多,线条柔和

此时频繁调用该耗费性能办法,

只能触发 6 次,画一段只能采集 6 个点,失常手速,就画进去一个多边形


能够这样优化,点的收集与绘制拆散

应用一个 Timer,每隔 0.15 秒,绘制一次

本来收集点,是一个 CGPoint,当初收集点,是一个 [CGPoint]

  • 本来画一次之前的 image,连一根线,更新图片变量并出现

n 个点, 来 n 次全画板绘制

  • 当初画一次之前的 image,连贯多根线,更新图片变量并出现

n 个点, 来 1 次全画板绘制

耗费性能的办法,少调用,就对了

    tempImageView.image?.draw(in: view.bounds)
    // ...
    
    tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()

前 4 点的代码,见 github

后续须要整顿,tbd

正文完
 0