第一步:新建一个工程:3DScrollView
第二步:创建一个类继承与Scrollview
#import
//枚举出3D效果的类型
typedef NS_ENUM(NSUInteger, JJJ3DScrollViewEffect)
{
JJJ3DScrollViewEffectNone,
JJJ3DScrollViewEffectTranslation,
JJJ3DScrollViewEffectDepth,
JJJ3DScrollViewEffectCarousel,
JJJ3DScrollViewEffectCards
};
@interface JJJ3DScorllView : UIScrollView
@property (nonatomic)JJJ3DScrollViewEffect effect;
@property (nonatomic)CGFloat angleRatio;
@property (nonatomic)CGFloat rotationX;
@property (nonatomic)CGFloat rotationY;
@property (nonatomic)CGFloat rotationZ;
@property (nonatomic)CGFloat translateZ;
@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
#import "JJJ3DScorllView.h"
#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
@implementation JJJ3DScorllView
- (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 = JJJ3DScrollViewEffectNone;
}
- (void)setEffect:(JJJ3DScrollViewEffect)effect
{
self->_effect = effect;
switch (effect) {
case JJJ3DScrollViewEffectTranslation:
self.angleRatio = 0.;
self.rotationX = 0.;
self.rotationY = 0.;
self.rotationZ = 0.;
self.translateX = .25;
self.translateY = .25;
break;
case JJJ3DScrollViewEffectDepth:
self.angleRatio = .5;
self.rotationX = -1.;
self.rotationZ = 0.;
self.rotationY = 0.;
self.translateX = .25;
self.translateY = 0.;
break;
case JJJ3DScrollViewEffectCarousel:
self.angleRatio = .5;
self.rotationX = -1.;
self.rotationY = 0.;
self.rotationZ = 0.;
self.translateX = .25;
self.translateY = .25;
break;
case JJJ3DScrollViewEffectCards:
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;
view.layer.transform = CATransform3DIdentity;
CGFloat distanceFromCenterX = view.frame.origin.x - contentOffsetX;
view.layer.transform = t1;
distanceFromCenterX = distanceFromCenterX*100. / CGRectGetWidth(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((int)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 fractionlPage = self.contentOffset.x/pageWidth;
return lround(fractionlPage);
}
- (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];
}
#import "ViewController.h"
#import "JJJ3DScorllView.h"
@interface ViewController ()<UIScrollViewDelegate>
@property (strong, nonatomic) JJJ3DScorllView *scrollView;
@property (strong, nonatomic) NSLayoutConstraint *leftNextButtonConstraint;
@property (strong, nonatomic) UIPageControl * pageControl;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView = [[JJJ3DScorllView alloc] init];
self.scrollView.frame = self.view.bounds;
[self.view addSubview:self.scrollView];
//设置动画形式(这里是个枚举值,可以在这里选择不同的效果)
self.scrollView.effect = JJJ3DScrollViewEffectCards;
self.scrollView.delegate = self;
//分页控件
self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-100, self.view.frame.size.width, 0)];
self.pageControl.numberOfPages = 4;
[self.view addSubview:self.pageControl];
[self createCardWithColor];
[self createCardWithColor];
[self createCardWithColor];
[self createCardWithColor];
}
-(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);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - scrollViewDelegate
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSInteger pageInt = scrollView.contentOffset.x/scrollView.frame.size.width;
self.pageControl.currentPage = pageInt;
self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];
}
@end