SCNNode map type

In AR development, we often map objects such as:

planeNode.geometry? .firstMaterial? .diffuse.contents = image cubeNode.geometry? .firstMaterial? .diffuse.contents = imageCopy the code

This way, but SCNNode type map there are many kinds of support, the official document notes basically has: UIColor, UIImage, CALayer, NSURL, SKScene SKTexture… It even supports AVCaptureDevice cameras and AVPlayer for playing video.

In actual development, I also found that UIView is also supported, size needs to be rounded, otherwise it may crash. In addition, I also found UIView as a texture, suspected of memory leakage: View and Node were destroyed, but the total memory of app kept increasing.

The UIView class is not currently recommended by apple (up to iOS13), which may have potential layout issues, memory issues, etc. Apple official employee responses on the BBS forums.developer.apple.com/message/340…

This can be a color (NSColor, UIColor, CGColorRef), 
an image (NSImage, UIImage, CGImageRef),
a layer (CALayer), a path (NSString or NSURL), a SpriteKit scene (SKScene),
a texture (SKTexture, id<MTLTexture> or GLKTextureInfo), 
or a floating value between 0 and 1 (NSNumber) forAVCaptureDevice is supported on iOS 11 and AVPlayer is supported on macOS 10.13. iOS 11 and tvOS 11.Copy the code

So which one should we use in actual development? What’s the difference?

Let’s try to understand the main UIImage, UIImageView, UIScrollView CALayer and the three types of distinction.

UIImage

The first one is UIImage, which looks like this after mapping

Animation support

UIImage itself cannot be animated, but the contentsTransform property is Animatable and can be used to animate morphs.

UIImageView

The way UIImageView maps is based on the value of the Frame. For example, the offset of x and y will affect the origin of the map. Size determines the sharpness. When size is width: 30, height: 30, and the cube is 1 meter wide and high, the effect is as follows.

When stretched, it will also be stretched and tiled, and when the X or y direction is offset, it will leave a distance on one side and truncate on the other. For example, a cuboid is empty at the top and truncated at the bottom:

Animation support

UIImageView, as a subclass of UIView, supports UIView animation and CAAnimation in normal development. However, in SCNNode maps, neither animation works.

You can use timers to change the frame value of UIImageView to change texture size and position, but there is no transition animation.

UIScrollView

UIScrollView is essentially the same as UIImageView, but in normal development in addition to UIView animation and CAAnimation, it also has Scroll animation.

How about this support? So let’s test that out

The support seems to be working well. Finally animating SCNNode textures!

CALayer

Since CALayer is usually pulled out of UIView, we’ll test it directly with the previous LAYER of UIImageView and UIScrollView. You can see that the basic performance is the same as UIImageView, but much lower resolution, for reasons unknown:

However, when the x and y of the frame are offset, the offset and truncation are not the same. Frame = CGRect(x: 0, y: 0, width: 30, height: 30) 20), so the coordinate system of CALayer and UIView is still different.

Animation support

In normal development, CALayer is an important animation layer and can do a lot of animations, but during the mapping, I found that all the CALayer animations didn’t work properly. What about the layer of UIScrollView? Does it still display Scroll animation properly?

Now to better distinguish between before and after images, I set the second image to UIImage() and make it black.

As you can see, CALyer can only display images of UIScrollView before and after scrolling, and does not display animations of the scrolling process in the middle.

There are three ways to animate: video, CALayer’s Sublayer animation, and SpriteKit

That is, animations for the outer CALayer are not supported, but manually creating a sublayer and adding animations is possible.

conclusion

type Resolution control The offset adjustment UIView animation CAAnimation Scroll effect
UIImage The picture itself is clear and cannot be adjusted Unable to offset adjustment
UIImageView Frame. Size clarity, adjustable Adjustable migration Does not support Does not support
UIScrollView Frame. Size clarity, adjustable Adjustable migration Does not support Does not support support
CALayer Lower resolution than frame. Size Adjustable offset, different effects Sublayer support Does not support

So, if you want to display a flat animation on a SCNNode map, consider using:

  • GIF or image array
  • UIScrollView scroll mode (officially not recommended)
  • Adjust the frame/color value of UIView or subclasses frame by frame (officially not recommended)
  • AVPlayer Plays video (official recommendation)
  • CALayer’s Sublayer Animation (official recommendation)
  • SKScene is the scene of the SpriteKit framework
    • Apple demonstrated this in session609 of WWDC2017

The most powerful of these is the SpriteKit framework, Apple’s 2D game development framework that allows you to create any animation you want. However, this framework is rarely used and performance problems are suspected in actual development.