2

I have an app that lets the user manipulate items like text, images, shapes (vector images). They are stacked on top of each other like layers are in Photoshop.

To manipulate means to translate, resize, rotate.

I use drawInRect to draw all my items. Unfortunately, when drawing images I see a very poor performance - this is the conclusion after inspecting the code with the profiler.

From what I've read online, people recommend using a separate UIView (UIImageView) for all the image drawing and normal drawInRect for the other stuff in a separate view.

But this approach would be problematic because I can have a situation like this:

  • 2 layers in the back with text
  • 1 layer with a image - obstructing part of the text
  • 2 layers in the front with text on top of the image

This would mean I would have to make a UIView for the first 2 text layers, an UIImageView for the middle image and another UIView for the front items. This seems unreasonable.

How can I improve the performance of my image drawing?

Also, keep in mind that I need to export this whole thing to a certain final image size.

NOTE: where I mention layer I'm not referring to CALayer.

Ilea Cristian
  • 5,741
  • 1
  • 23
  • 37
  • delay the rendering of draws. Take user input, like resizing etc, perform it in a separate thread, get the result and replace the current image with it. In short instead of doing the manipulations in main thread on main uimageview. Do the manipulations in a separate thread with different image and replace that new manipulated image with the current one being displayed... Or this is not an option? and instead it is a requirement to do draws in real time? – Rana Tallal May 09 '18 at 07:33

1 Answers1

1

Use a method like this to draw what you want:

func drawSomeImage(completion: (UIImage) -> Void) {

        UIGraphicsBeginImageContextWithOptions(<#T##size: CGSize##CGSize#>, <#T##opaque: Bool##Bool#>, <#T##scale: CGFloat##CGFloat#>)

        //Your drawing...

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
       completion(image)
}

And do the above lines in a thread out of the main thread like this:

 func myImage() {

        DispatchQueue.global().async {


          drawSomeImage { image in


            DispatchQueue.main.async {

               //use this image in your main thread like:
              //self.imageView.image = image

           }

         }

        }