4
votes

I’m working on various iOS apps and I need an interface with the following capabilities:

  1. I have a scrollview (covering most of the screen) which is scrollable both directions

  2. This scrollable view contains a lot of rectangles. These rectangles are intractable. User can modify them, move them around, create and delete. So ideally they would be all CALayers or UIViews.

  3. The problem is because there could be 100s or 1000s of those displayed at once, CALayers or UIViews may not be very efficient.

  4. The scrollview could be 10-20 times bigger than the screen size itself. And fully covered with these shapes. So when the user scrolls it shouldn’t see any flickers or shapes appearing after the scrolling is done. e.g. If I use CATiledLayer and user scrolls, you can see things drawn after scrolling is done.

  5. Smooth zooming. Zooming out is particularly challenging, because the shapes would need to be drawn on parts of the view which are going to become visible. Also, ideally I’d rather not use something like CGAffineTransform to perform scaling, I like to have a pixel accurate scaling.

I’ve tried various things, but I can’t seem to be able to get decent frame rates even on iPhone 6. Even tried drawing every frame, but it’s too expensive Core Graphics to handle it. Is there code examples someone trying to do a similar thing or an open source library? I’m trying not to use OpenGL, I feel like it’s an overkill, but I will try it if I have to. FYI, I have no experience in OpenGL yet.

Procreate for iPad does what I’m trying to do perfectly, it’s super responsive and zooming is pixel accurate. I know they use OpenGL and I’m not making drawing apps. The reason I mention it is because it shows what I’m trying to do is possible.

1
Could you add a bit more data on those "rectangles" and their content. Are they simply field with color or do they have some graphical content such as images, subviews or subrects? Do you expect some transparency? Do they have strange shapes such as rounded corners... Even openGL may not save you in some cases.Matic Oblak
They are plain rectangles with single fill colour. No rounded corners, strange shapes, no content or subviews. It's kind of like what you get when you open a MIDI region in GarageBand (iOS) to edit it.Nikolozi
I created a fullscreen scroll view of content size 10kx10k and added 2000 subviews on random places inside the content view with sizes from 200 to 400 points per dimension with random colors and ran it on iPhone5 and has just a small lag when zooming out fully. That seems quite a large number. The core graphics is most likely slower then that and is a bad idea; Tiling will never have a better performance, only possibly a lower memory footprint but not in your case. I guess it should be faster with openGL but do not expect magic to happen on its own.Matic Oblak
Cheers for trying that. I've been experimenting with OpenGL and Metal past few days, seems like a lot of work just to get basics drawn. But I'll admit, per frame rendering with those APIs make it an attractive choice. Having said that, I just discovered CALayer has drawsAsynchronously property. So I'll see how adding CALayers to only visible area and removing when they are offscreen performs. Hopefully, it doesn't flicker too much.Nikolozi
You can do that on the UIView by hiding them or even removing them from the super view. I am sorry to disappoint you but you will not gain much performance this way. The problem is in the back that for drawing N views you need N draw calls (can be optimized with openGL). Then for each view that IS on the screen you have as many fragments as visible pixels (which is a lot), this can be optimized with both UIView or the openGL but is quite hard as you need to create a system that detects the overlapping and draws only the subrects.Matic Oblak

1 Answers

1
votes

I think you need to move from UIKit to some 2d or 3d engines:

  • Cocos2D
  • Sparrow
  • Unity
  • OOlong