Without OpenGL ES, how to use CoreAnimation to realize a cube and rotate it, the overall effect is as follows

The whole idea is as follows

It is mainly divided into two parts

  • ViewDidLoad function: initializes work
  • Update: The timer is rotated

ViewDidLoad function

Initialization consists of two parts:

  • AddFaces: Add 6 faces and transform them into cubes
  • AddCADisplayLink: Adds a timer and a runloop

The addFaces function basically adds the six faces to the container with corresponding transformations

  • OC version
// addFaces - (void)addFaces{self.faces = @[_view0, _view1, _view2, _view3, _view4, _view5]; // Main view CATransform3D perspective = CATransform3DIdentity; // Set the core animation to perspective.m34 = -1.0/500.0; // Rotate around x and y respectively, M_PI_4 = π/4, π=180° Perspective = CATransform3DRotate(perspective, -m_PI_4, 1, 0, 0); perspective = CATransform3DRotate(perspective, -M_PI_4, 0, 1, 0); self.containerView.layer.sublayerTransform = perspective; // Add face1 // z-shift 100 // The rest of the view are based on the position of the first view on translation + rotation) CATransform3D transform = CATransform3DMakeTranslation (0, 0, 100); [self addFace:0 withTransform:transform]; / / / / add face2 - translation + y rotation transform = y CATransform3DMakeTranslation (100, 0, 0). transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0); [self addFace:1 withTransform:transform]; / / / / add face3 - translation + rotation transform x = y CATransform3DMakeTranslation (0-100, 0); transform = CATransform3DRotate(transform, M_PI_2, 1, 0, 0); // [self addFace:2 withTransform:transform]; / / add face4 - translation + rotation transform x = y CATransform3DMakeTranslation (0, 100, 0); transform = CATransform3DRotate(transform, -M_PI_2, 1, 0, 0); [self addFace:3 withTransform:transform]; / / add face5 - translation + rotation transform = CATransform3DMakeTranslation (- 100, 0, 0); transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0); [self addFace:4 withTransform:transform]; / / add face6 - translation + z rotation transform = y CATransform3DMakeTranslation (0, 0, - 100); transform = CATransform3DRotate(transform, M_PI, 0, 1, 0); [self addFace:5 withTransform:transform]; } - (void)addFace: (NSInteger)index withTransform: (CATransform3D)transform {// Get the face view and add it to the container UIView *face = self.faces[index]; [self.containerView addSubview:face]; / / will face in the center of the container view CGSize containerSize = self. ContainerView. Bounds. Size; Face. Center = CGPointMake (containerSize. Width / 2.0, containerSize height / 2.0); // Add tansForm, tansform is a matrix face.layer.transform = transform; }Copy the code
  • Swift version
Func addFaces(){faces = [view0, view1, view2, view3, view4, view5] CATransform3D = CATransform3DIdentity perspective.m34 = -1.0/500.0 perspective = CATransform3DRotate(perspective, -.pi/4, 1, 0, 0) perspective = CATransform3DRotate(perspective, -.pi/4, 0, 1, 0) self. ContainerView. Layer. Add face1 sublayerTransform = perspective / / var transform = CATransform3DMakeTranslation (0, 0, 100). The self addFaceWithTransform (0, the transform) / / add face2 transform = CATransform3DMakeTranslation (100, 0, 0) transform = CATransform3DRotate(transform, .pi/2, 0, 1, 0) self.addFaceWithTransform(1, The transform) / / add face3 transform = CATransform3DMakeTranslation (0-100, 0) // transform = CATransform3DRotate(transform, .pi/2, 1, 0, 0) // self.addFaceWithTransform(2, The transform) / / / / add face4 transform = CATransform3DMakeTranslation (0, 100, 0) transform = CATransform3DRotate (the transform, -. The PI / 2, 1, 0, 0) self. AddFaceWithTransform (3, the transform) / / / / add face5 transform = CATransform3DMakeTranslation (- 100, 0, 0) // transform = CATransform3DRotate(transform, -.pi/2, 0, 1, 0) self.addFaceWithTransform(4, The transform) / / / / / / add face6 / / transform = CATransform3DMakeTranslation (0, 0, -100) // transform = CATransform3DRotate(transform, .pi, 0, 1, 0) // self.addFaceWithTransform(5, transform) } private func addFaceWithTransform(_ index: Int, _ transform: CATransform3D){// Get face, And add to the container let face = self. Faces [index] self. ContainerView. AddSubview (face) / / will face view into the center of the container let containerSize = self.containerView.bounds.size face.center = CGPoint(x: containerSize.width/2, y: ContainerSize. Height /2) // Add transform face.layer.transform = transform}Copy the code

The addCADisplayLink function initializes the timer and adds the timer to the Runloop

  • OC version
// Add timer - (void)addCADisplayLink{self. Angle = 0; self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)]; [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; }Copy the code
  • Swift version
fileprivate func addCADisplayLink(){
    self.displayLink.add(to: RunLoop.main, forMode: .common)
   }

Copy the code

The update to update

The main thing is to calculate the degree of rotation and rotate the container’s child layer around in any direction

  • OC version
- (void)update{self. Angle = (self. Angle + 5) % 360; Float deg = self. Angle * (M_PI / 180); float deg = self. Angle * (M_PI / 180); CATransform3D temp = CATransform3DIdentity; // Temp = CATransform3DRotate(temp, deG, 0.3, 1, 0.7); / / rotating container of sub layer self. ContainerView. Layer. SublayerTransform = temp; }Copy the code
  • Swift version
@objc fileprivate func update(){ self.angle = (self.angle+5).truncatingRemainder(dividingBy: 360) let deg = self.angle * (.pi/180) var temp = CATransform3DIdentity temp = CATransform3DRotate(temp, CGFloat(deg), 0.3, 1, 0.7) self. ContainerView. Layer. SublayerTransform = temp}Copy the code

For the complete code, see Github-09_coreAnimation_ cube + rotate OC and 09_CoreAnimation Cube + rotate _Swift, which are available in OC and Swift versions, respectively