用scrollview制作3D效果的导航页





第一步:新建一个工程:3DScrollView

第二步:创建一个类继承与Scrollview


#import <UIKit/UIKit.h>


//枚举出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, nonatomicJJJ3DScorllView *scrollView;

@property (strong, nonatomicNSLayoutConstraint *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


OK,完工了,就是这么简单。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值