首先导入JT3DScrollView.h和m文件到工程(详细代码可到code4APP网站下载)
只要在要使用的类中初始化JT3DScrollView类即可使用,它继承于UIScrollerView,使用时与UIScrollerView的方法相同,设置实例化对象的属性effect,它有如下几种效果可选择:JT3DScrollViewEffectNone,
JT3DScrollViewEffectTranslation,
JT3DScrollViewEffectDepth,
JT3DScrollViewEffectCarousel,
JT3DScrollViewEffectCards
要在滚动视图中添加视图可通过如下的例子来添加,当然,要初始化多个可以通过for循环调用下面的方法来实现,每调用一次初始化一个,
- (void)createCardWithColor
{
CGFloat width = CGRectGetWidth(self.scrollView.frame);
CGFloat height = CGRectGetHeight(self.scrollView.frame);
CGFloat x = self.scrollView.subviews.count * width;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, 0, width, height)];
view.backgroundColor = [UIColor colorWithRed:33/255. green:158/255. blue:238/255. alpha:1.];
view.layer.cornerRadius = 8.;
[self.scrollView addSubview:view];
self.scrollView.contentSize = CGSizeMake(x + width, height);//设置滚动视图的内容大小
}
下面举例一种效果的实现:
效果如图所示;
只要在JT3DScrollView.m文件中修改 switch case中的JT3DScrollViewEffectTranslation为:
case JT3DScrollViewEffectTranslation:
self.angleRatio = 0.3;
self.rotationX = 0.4;
self.rotationY = 0.;
self.rotationZ = 0.;
self.translateX = .25;
self.translateY = .0;
break;
就可以实现效果。当然实例化对象的effect也要设置为JT3DScrollViewEffectTranslation。
JT3DScrollView.h文件
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, JT3DScrollViewEffect) {
JT3DScrollViewEffectNone,
JT3DScrollViewEffectTranslation,
JT3DScrollViewEffectDepth,
JT3DScrollViewEffectCarousel,
JT3DScrollViewEffectCards
};
@interface JT3DScrollView : UIScrollView
@property (nonatomic) JT3DScrollViewEffect effect;
@property (nonatomic) CGFloat angleRatio;
@property (nonatomic) CGFloat rotationX;
@property (nonatomic) CGFloat rotationY;
@property (nonatomic) CGFloat rotationZ;
@property (nonatomic) CGFloat translateX;
@property (nonatomic) CGFloat translateY;
- (NSUInteger)currentPage;
- (void)loadNextPage:(BOOL)animated;
- (void)loadPreviousPage:(BOOL)animated;
- (void)loadPageIndex:(NSUInteger)index animated:(BOOL)animated;
@end
JT3DScrollView.m文件
#import "JT3DScrollView.h"
#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
@implementation JT3DScrollView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(!self){
return nil;
}
[self commonInit];
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if(!self){
return nil;
}
[self commonInit];
return self;
}
- (void)commonInit
{
self.pagingEnabled = YES;
self.clipsToBounds = NO;
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
self.effect = JT3DScrollViewEffectNone;
}
- (void)setEffect:(JT3DScrollViewEffect)effect
{
self->_effect = effect;
switch (effect) {
case JT3DScrollViewEffectTranslation:
self.angleRatio = 0.;
self.rotationX = 0.;
self.rotationY = 0.;
self.rotationZ = 0.;
self.translateX = .25;
self.translateY = .25;
break;
case JT3DScrollViewEffectDepth:
self.angleRatio = .5;
self.rotationX = -1.;
self.rotationY = 0.;
self.rotationZ = 0.;
self.translateX = .25;
self.translateY = 0.;
break;
case JT3DScrollViewEffectCarousel:
self.angleRatio = .5;
self.rotationX = -1.;
self.rotationY = 0.;
self.rotationZ = 0.;
self.translateX = .25;
self.translateY = .25;
break;
case JT3DScrollViewEffectCards:
self.angleRatio = .5;
self.rotationX = -1.;
self.rotationY = -1.;
self.rotationZ = 0.;
self.translateX = .25;
self.translateY = .25;
break;
default:
self.angleRatio = 0.;
self.rotationX = 0.;
self.rotationY = 0.;
self.rotationZ = 0.;
self.translateX = 0.;
self.translateY = 0.;
break;
}
[self setNeedsDisplay];
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat contentOffsetX = self.contentOffset.x;
CGFloat contentOffsetY = self.contentOffset.y;
for(UIView *view in self.subviews){
CATransform3D t1 = view.layer.transform; // Hack for avoid visual bug
view.layer.transform = CATransform3DIdentity;
CGFloat distanceFromCenterX = view.frame.origin.x - contentOffsetX;
// CGFloat distanceFromCenterY = view.frame.origin.y - contentOffsetY;
view.layer.transform = t1;
distanceFromCenterX = distanceFromCenterX * 100. / CGRectGetWidth(self.frame);
// distanceFromCenterY = distanceFromCenterY * 100. / CGRectGetHeight(self.frame);
CGFloat angle = distanceFromCenterX * self.angleRatio;
CGFloat offset = distanceFromCenterX;
CGFloat translateX = (CGRectGetWidth(self.frame) * self.translateX) * offset / 100.;
CGFloat translateY = (CGRectGetWidth(self.frame) * self.translateY) * abs(offset) / 100.;
CATransform3D t = CATransform3DMakeTranslation(translateX, translateY, 0.);
view.layer.transform = CATransform3DRotate(t, DEGREES_TO_RADIANS(angle), self.rotationX, self.rotationY, self.rotationZ);
}
}
- (NSUInteger)currentPage
{
CGFloat pageWidth = self.frame.size.width;
float fractionalPage = self.contentOffset.x / pageWidth;
return lround(fractionalPage);
}
- (void)loadNextPage:(BOOL)animated
{
[self loadPageIndex:self.currentPage + 1 animated:animated];
}
- (void)loadPreviousPage:(BOOL)animated
{
[self loadPageIndex:self.currentPage - 1 animated:animated];
}
- (void)loadPageIndex:(NSUInteger)index animated:(BOOL)animated
{
CGRect frame = self.frame;
frame.origin.x = frame.size.width * index;
frame.origin.y = 0;
[self scrollRectToVisible:frame animated:animated];
}
@end