iOS development | two sided view

Posted by nbarone on Sun, 31 May 2020 13:20:05 +0200

iu

To rotate a view 180 degrees around the y-axis is like this:


Rotate.gif

On the front:


positive

On the reverse:


the other side

Sometimes we may need to set the back to a different picture or view, as follows:

two-sided view.gif

How to achieve this effect?

My thoughts:

Put two views in turn on a transparent view. The bottom view is the bottom view, and the top view is the top view. Rotate the bottom view 180 degrees. When flipping, rotate the transparent view 180 degrees.

Why rotate the bottom view 180 degrees?

If you do not rotate, the effect is as follows:


The picture is the opposite.gif

The picture is the opposite. In order to get the correct picture after 180 degrees of rotation, you have to rotate it 180 degrees first, so it is positive after two 180 degrees of rotation. That's why you need to rotate the bottom view 180 degrees first.

When to switch between two view s?

When the animation is halfway through, move the bottom view up.

Code implementation:

This is a custom view

. h file:

#import <UIKit/UIKit.h>

@interface TwoSidedView : UIView

/** Top view */
@property (nonatomic, strong) UIView *topView;
/** Bottom view */
@property (nonatomic, strong) UIView *bottomView;

/**
 Flip

 @param duration Time to flip the animation
 @param completion Callback after animation
 */
- (void)turnWithDuration:(NSTimeInterval)duration completion:(void(^)(void))completion;

@end

. m file:

#import "TwoSidedView.h"

@implementation TwoSidedView

/** Set top view */
- (void)setTopView:(UIView *)topView {
    _topView = topView;
    
    [self addSubview:topView];
    [self bringSubviewToFront:_topView];
}

/** Set bottom view */
- (void)setBottomView:(UIView *)bottomView {
    _bottomView = bottomView;
    
    [self addSubview:_bottomView];
    [self sendSubviewToBack:_bottomView];
    
    // Flip 180 degrees
    CATransform3D transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
    _bottomView.layer.transform = transform;
}

/**
 Flip
 
 @param duration Time to flip the animation
 @param completion Callback after animation
 */
- (void)turnWithDuration:(NSTimeInterval)duration completion:(void(^)(void))completion{
    if (!self.topView || !self.bottomView) {
        NSAssert(NO, @"Not set topView or bottomView");
    }
    
    // Move the bottom view to the top half of the animation
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration / 2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self bringSubviewToFront:self.bottomView];
    });
    
    // Flip 180 degrees
    [UIView animateWithDuration:duration animations:^{
        CATransform3D transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
        self.layer.transform = transform;
    } completion:^(BOOL finished) {
        if (completion) {
            completion();
        }
    }];
}

@end

This is demo