`
jsntghf
  • 浏览: 2533858 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

UIView转场效果

    博客分类:
  • iOS
阅读更多

核心功能如代码所示,其他的请参考附件。

 

 

FlipTransView.h

 

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

#define PAGE_VERTICAL_WIDTH                      320.0f
#define PAGE_VERTICAL_HEIGHT                     480.0f
#define PAGE_HORIZONTAL_WIDTH                    480.0f
#define PAGE_HORIZONTAL_HEIGHT                   300.0f

@class FlipTransView;

@protocol FlipTransViewDelegate <NSObject>
@optional
- (void)FlipTransViewDidStart:(FlipTransView *)view;
- (void)FlipTransViewDidFinish:(FlipTransView *)view;
- (void)FlipTransViewDidCancel:(FlipTransView *)view;
@end

typedef enum {
    LTOR = 0,
    RTOL,
} TranDirection;

@interface FlipTransView : UIView {
    id<FlipTransViewDelegate> m_pDelegate;
@private
    CALayer		*m_pTransformed;
    UIView		*m_pSubView;
    UIView		*m_pNewView;
    BOOL		m_bTransitioning;
	BOOL		m_bEnabled;
}

@property (nonatomic, retain) UIView *m_pSubView;
@property (assign) id<FlipTransViewDelegate> m_pDelegate;
@property (readonly, getter = isTransitioning) BOOL m_bTransitioning;

- (void)replaceSubviewInCube:(UIView *)aNewView direction:(TranDirection)aDirection duration:(float)aDuration;
- (void)replaceSubviewInCube:(UIView *)aNewView direction:(TranDirection)aDirection duration:(float)aDuration isMasked:(BOOL)aIsMasked;
@end

 

FlipTransView.m

 

#import "FlipTransView.h"

#define radians(degrees) degrees * M_PI / 180
#define CUBE_VERTICAL_WIDTH PAGE_VERTICAL_WIDTH
#define CUBE_VERTICAL_HEIGHT PAGE_VERTICAL_HEIGHT
#define CUBESIZE 320.0f
#define MASKALPHA 0.4f

#define kAnimationKey @"FlipTransViewAnimation"

@implementation FlipTransView

@synthesize m_pSubView;
@synthesize m_pDelegate;
@synthesize m_bTransitioning;

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
		m_pSubView = nil;
        m_bTransitioning = NO;
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

- (void)addSubview:(UIView *)view {
    if (view != nil) {
        self.m_pSubView = view;
        [super addSubview:view];
    }
}

- (id) captureView:(UIView*)view {
    UIGraphicsBeginImageContext(view.frame.size);
	[view.layer renderInContext:UIGraphicsGetCurrentContext()];
	CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), true);
	UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
    
	return (id) [newImage CGImage];
}

- (id) captureView:(UIView *)view isMasked:(BOOL)aIsMasked {
    UIGraphicsBeginImageContext(view.frame.size);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
	CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), true);
    
	if (aIsMasked) {
        CGContextSetRGBFillColor (UIGraphicsGetCurrentContext(), 0, 0, 0, MASKALPHA);
        CGContextFillRect (UIGraphicsGetCurrentContext(), view.frame);
    }
	
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
    
    return (id) [newImage CGImage];
}

- (CALayer*) makeSurface:(CATransform3D)t withView:(UIView *)aNewView isMasked:(BOOL)aIsMasked {
    CGRect rect = CGRectMake(0, 0, CUBE_VERTICAL_WIDTH, CUBE_VERTICAL_HEIGHT);
    
    CALayer *imageLayer = [CALayer layer];
    imageLayer.anchorPoint = CGPointMake(1, 1);
    imageLayer.frame = rect;
    imageLayer.transform = t; 
    imageLayer.contents = [self captureView:aNewView isMasked:aIsMasked];
    return imageLayer;
}

- (void)constuctRotateLayer:(UIView *)aNewView direction:(TranDirection)aDirection isMasked:(BOOL)aIsMasked {
    //init transformed Layer
    m_pTransformed = [CALayer layer];
    m_pTransformed.frame = self.bounds;
    m_pTransformed.anchorPoint = CGPointMake(0.5f, 0.5f);
    CATransform3D sublayerTransform = CATransform3DIdentity;
	
    /* Set perspective */ 
    sublayerTransform.m34 = 1.0 / -1000;
    [m_pTransformed setSublayerTransform:sublayerTransform];
    
    [self.layer addSublayer:m_pTransformed];
    //init Sublayers
    CATransform3D t = CATransform3DMakeTranslation(0, 0, 0);
	[m_pTransformed addSublayer:[self makeSurface:t withView:m_pSubView isMasked:aIsMasked]];
	[m_pSubView setHidden:YES];

	t = CATransform3DMakeTranslation(0, 0, 0);
	t = CATransform3DTranslate(t, 320, 0, 0);
	t = CATransform3DRotate(t, radians(90), 0, 1, 0);
	CGRect rect = CGRectMake(0, 0, 40, 480);
	CALayer *imageLayer = [CALayer layer];
	imageLayer.anchorPoint = CGPointMake(0, 0);
	imageLayer.frame = rect;
	imageLayer.transform = t; 
	CGImageRef subimage=CGImageCreateWithImageInRect([UIImage imageNamed:@"green_bg_home.png"].CGImage, rect);
	CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), true);
	imageLayer.contents=(id)subimage;
	CFRelease(subimage);
	[m_pTransformed addSublayer:imageLayer];
	
	t = CATransform3DMakeTranslation(0, 0, 0);
	t = CATransform3DTranslate(t, 0, 0, -40);
	t = CATransform3DRotate(t, radians(180), 0, 1, 0);
	rect = CGRectMake(0, 0, 320, 480);
	imageLayer = [CALayer layer];
	imageLayer.anchorPoint = CGPointMake(0.5, 0.5);
	imageLayer.frame = rect;
	imageLayer.transform = t;  
	imageLayer.contents = [self captureView:aNewView isMasked:aIsMasked];
	[m_pTransformed addSublayer:imageLayer];
}

- (void)destroyRotateLayer {
    [m_pTransformed removeFromSuperlayer];
}

- (void)moveFrom:(TranDirection)aDirection duration:(float)aDuration {
    [CATransaction flush];
    CABasicAnimation *rotation;
    CABasicAnimation *translationX;
    CABasicAnimation *translationZ;
    CAAnimationGroup *group = [CAAnimationGroup animation]; 
    group.delegate = self; 
    group.duration = aDuration; 

	translationX = [CABasicAnimation animationWithKeyPath:@"sublayerTransform.translation.x"];
	translationX.toValue = [NSNumber numberWithFloat:0.0];
	rotation = [CABasicAnimation animationWithKeyPath:@"sublayerTransform.rotation.y"]; 
	rotation.toValue = [NSNumber numberWithFloat:radians(-180)];
	translationZ = [CABasicAnimation animationWithKeyPath:@"sublayerTransform.translation.z"];
	translationZ.toValue = [NSNumber numberWithFloat:0.0];
	
    group.animations = [NSArray arrayWithObjects: rotation, nil];
    group.fillMode = kCAFillModeForwards; 
    group.removedOnCompletion = NO;
    [m_pTransformed addAnimation:group forKey:kAnimationKey];
}

- (void)replaceSubviewInCube:(UIView *)aNewView direction:(TranDirection)aDirection duration:(float)aDuration {
    [self replaceSubviewInCube:aNewView direction:aDirection duration:aDuration isMasked:NO];
}

- (void)replaceSubviewInCube:(UIView *)aNewView direction:(TranDirection)aDirection duration:(float)aDuration isMasked:(BOOL)aIsMasked {
    // If a transition is in progress, do nothing
	if(m_bTransitioning || aNewView == nil)
        return;
    //If there's a new view and it doesn't already have a superview, insert it where the old view was
	if (m_pSubView == nil) {
        [self addSubview:aNewView];
        return;
    }
    
    if ([aNewView superview] != nil) {
        [aNewView removeFromSuperview];
	}
    m_pNewView = aNewView;
	
    [self constuctRotateLayer:aNewView direction:aDirection isMasked:NO];
    [self moveFrom:aDirection duration:aDuration];
}

// Not used in this example, but may be useful in your own project
- (void)cancelTransition {
	// Remove the animation -- cleanup performed in animationDidStop:finished:
	[[self layer] removeAnimationForKey:kAnimationKey];
}

- (void)animationDidStart:(CAAnimation *)animation {
	m_bTransitioning = YES;
    [m_pSubView removeFromSuperview];
    [m_pSubView setHidden:NO];
    // Record the current value of userInteractionEnabled so it can be reset in animationDidStop:finished:
    m_bEnabled = self.userInteractionEnabled;
	
	// If user interaction is not already disabled, disable it for the duration of the animation
	if (m_bEnabled) {
		self.userInteractionEnabled = NO;
    }
    
	// Inform the delegate if the delegate implements the corresponding method
	if(m_pDelegate != nil && [m_pDelegate respondsToSelector:@selector(FlipTransViewDidStart:)]) {
		[m_pDelegate FlipTransViewDidStart:self];
    }
}

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished {
	m_bTransitioning = NO;
    [self addSubview:m_pNewView];
    [self destroyRotateLayer];
    m_pNewView = nil;
    
	// Reset the original value of userInteractionEnabled
	if (m_bEnabled) {
		self.userInteractionEnabled = YES;
    }
    
	// Inform the delegate if it implements the corresponding method
	if (finished) {
		if (m_pDelegate != nil && [m_pDelegate respondsToSelector:@selector(FlipTransViewDidFinish:)]) {
			[m_pDelegate FlipTransViewDidFinish:self];
        }
	} else {
		if (m_pDelegate != nil && [m_pDelegate respondsToSelector:@selector(FlipTransViewDidCancel:)]) {
			[m_pDelegate FlipTransViewDidCancel:self];
        }
	}
}

- (void)dealloc {
	[m_pSubView release];
    [super dealloc];
}

@end
 

 示例图:


分享到:
评论

相关推荐

    详解iOS开发中的转场动画和组动画以及UIView封装动画

    CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点 UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果 属性解析...

    iOS-自定义转场动画

    在iOS开发中,自定义转场动画是一种提升用户体验的有效手段,它可以让你的应用界面在页面切换时展现出独特的视觉效果。本文将深入探讨自定义转场动画的相关知识点,帮助开发者更好地理解和应用这一技术。 首先,转...

    swift-Swift图片遮罩转场动画效果

    在Swift中,我们通常会使用UIView动画来实现转场效果。UIView动画提供了简单的API来创建平滑的动画,包括淡入淡出、缩放、旋转等。结合遮罩技术,我们可以在动画过程中改变遮罩的形状或位置,从而实现图片的动态变化...

    转场动画Demo

    "转场动画Demo"是一个展示如何在应用中实现平滑、引人入胜的过渡效果的项目。这个Demo可能包含了一个简单的单视图转场动画,旨在帮助开发者理解并应用这类动画到自己的应用中。 转场动画在iOS中的应用广泛,它们...

    ios-一句话搞定圆形扩散转场动画.zip

    "一句话搞定圆形扩散转场动画"是一个针对iOS平台的特定动画实现,它旨在通过简洁的代码实现一个具有视觉冲击力的圆形扩散转场效果。 在iOS中,我们可以使用Core Animation或者UIKit提供的动画框架来创建各种动画,...

    ios-照片选择器转场动画.zip

    本项目"ios-照片选择器转场动画.zip"重点展示了如何在照片选择器中实现平滑的转场效果,特别是针对视图动画的运用。 首先,我们要理解转场动画的基本概念。转场动画是指在两个视图之间切换时,通过动画效果来呈现...

    iOS-多媒体-转场动画-卡片转场效果-类似于AppStore中的效果-18Hero5-Card

    本教程将深入探讨如何实现一个“卡片转场效果”,这种效果常见于App Store和其他许多高质量的应用中,例如18Hero5-Card。我们将主要关注iOS中的多媒体和动画技术,以及如何通过代码来创建类似的效果。 首先,我们要...

    自定义 UIView的阴影效果

    在iOS开发中,自定义UIView的阴影效果是一个常见的需求,它可以为UI元素增添层次感和专业性。在本文中,我们将深入探讨如何实现这个功能,包括设置阴影颜色、阴影偏移、阴影透明度以及阴影半径等关键参数。 首先,...

    iOS转场动画

    2. 创建转场:通过设置CATransition的type和subtype属性,可以创建不同类型的转场效果。例如,type="kCATransitionFade"表示淡入淡出效果,subtype="kCATransitionFromLeft"表示从左侧推入效果。 3. 设置时长和速度...

    动画组和转场动画Demo

    除了使用`UIViewControllerTransitioningDelegate`,iOS还提供了一些类方法来快速实现常见的转场效果,例如`UIView.transition(with:duration:options:animations:completion:)`。这个方法可以方便地在两个视图之间...

    ios-自定义转场动画.zip

    在iOS开发中,自定义转场动画是一种提升用户体验的有效手段,它可以让你的应用界面在切换页面时展现出独特的视觉效果。这个“ios-自定义转场动画.zip”文件包含了一个名为"CustomTransition(Swift)"的项目,很可能是...

    Swift 4 转场动画全部

    Swift 4 转场动画是iOS应用开发中一种引人注目的视觉效果,它可以增强用户体验,使得页面间的切换更加流畅自然。在Swift 4中,开发者可以利用`UIViewControllerAnimatedTransitioning`和`...

    swift-AppStoreairbnb转场的控件移动效果实现

    在Swift编程语言中,App Store和Airbnb应用的转场效果是通过自定义视图控制器转场来实现的。这种转场效果不仅提升了用户体验,也增加了应用的视觉吸引力。为了达到这种效果,开发者通常需要对iOS的UIKit框架有深入的...

    ios-上拉转场动画.zip

    在iOS应用开发中,上拉转场动画是一种常见的交互效果,用于给用户带来更生动、流畅的界面切换体验。这种动画通常应用于底部弹出新视图或者关闭当前视图的情景,例如显示更多内容、加载数据或展示详情。在本案例中,...

    iOS-多媒体-转场动画-设置 转场过程中-前后俩个页面中的指定View的转场动画-15Hero2-match

    例如,我们可以创建一个扩展,为特定的视图创建匹配的转场效果: ```swift extension YourViewController: UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { func animation...

    iOS如何利用一句话完成转场动画

    首先,SS_AnimationTransition库提供了一个简单易用的接口,使得开发者无需深入了解转场动画的底层实现,就能快速地在应用中添加各种类型的转场效果。这个库具有高内聚、低耦合的特性,降低了对项目原有结构的影响,...

    ios UIView或者UIViewController缩放动画效果

    在iOS开发中,实现视图(UIView)或控制器(UIViewController)的缩放动画效果是常见的交互设计,可以增强用户体验并使界面更具动态美感。这里我们将深入探讨如何在iOS应用中创建这种效果,以及如何通过自定义Dome...

    swift-UIWindow转场动画及案例分析

    当然,你还可以选择其他转场效果,如`.transitionFlipFromLeft`(翻页效果)或`.transitionFlipFromRight`。 如果默认的动画选项无法满足需求,我们可以进一步使用`CATransition`类来自定义更复杂的转场动画。`...

    ios-控制器转场-- 抽屉效果,支持手势.zip

    本压缩包文件着重介绍了如何实现一种特殊的转场效果——抽屉效果,同时它还模仿了QQ个人信息页面的转场动画以及App Store中的卡片动画。这些效果为应用程序提供了更加动态和丰富的用户体验。 首先,抽屉效果是iOS...

Global site tag (gtag.js) - Google Analytics