| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- //
- // CCZTrotingView.m
- // CCZTrotView
- //
- // Created by 金峰 on 16/9/22.
- // Copyright © 2016年 金峰. All rights reserved.
- //
- #import "CCZTrotingView.h"
- typedef void(^trotingBlock)();
- @interface CCZTrotingView ()<CAAnimationDelegate>
- @property (nonatomic, assign) CGSize size;
- @property (nonatomic, strong) UIImageView *backgroundImageView;
- @property (nonatomic, strong) CAKeyframeAnimation *trotingXAnimation;
- @property (nonatomic, strong) CAKeyframeAnimation *trotingYAnimation;
- @property (nonatomic, strong) NSMutableArray *trotViewArr; /**< 用于存放待滚动的view的*/
- @property (nonatomic, copy) trotingBlock stopBlock;
- @property (nonatomic, copy) trotingBlock startBlock;
- @property (nonatomic, copy) trotingBlock trotingBlock;
- @end
- @implementation CCZTrotingView
- - (instancetype)initWithFrame:(CGRect)frame {
- self = [super initWithFrame:frame];
- if (self) {
- [self __basicSetting];
- [self __pageSetting];
- }
- return self;
- }
- - (instancetype)init {
- self = [super init];
- if (self) {
- [self __basicSetting];
- [self __pageSetting];
- }
- return self;
- }
- - (void)__basicSetting {
- self.backgroundColor = [UIColor whiteColor];
- _direction = CCZTrotDirectionLeft; // 从最右侧滚入,左侧滑出
- _duration = 10;
- _pause = 0.0;
- _autoTrotingRepeat = NO;
- _isTroting = NO;
- _hideWhenStopTroting = NO;
- _trotViewArr = [NSMutableArray arrayWithCapacity:1];
- }
- - (void)__pageSetting {
- _backgroundImageView = [[UIImageView alloc] init];
- _backgroundImageView.userInteractionEnabled = YES;
- [self addSubview:_backgroundImageView];
-
- _trotContaierView = [[UIView alloc] init];
- _trotContaierView.clipsToBounds = YES;
- [self addSubview:_trotContaierView];
- }
- - (void)layoutSubviews {
- _size = self.frame.size;
- _backgroundImageView.frame = self.bounds;
-
- if (self.leftView) {
- CGSize leftSize = self.leftView.frame.size;
- self.leftView.frame = CGRectMake(10, (_size.height - leftSize.height) / 2, leftSize.width, leftSize.height);
- }
-
- if (self.rightView) {
- CGSize rightSize = self.rightView.frame.size;
- self.rightView.frame = CGRectMake(_size.width - rightSize.width, (_size.height - rightSize.height) / 2, rightSize.width, rightSize.height);
- }
-
- self.trotContaierView.frame = CGRectMake(CGRectGetMaxX(self.leftView.frame), 0, _size.width - CGRectGetWidth(self.leftView.frame) - CGRectGetWidth(self.rightView.frame), _size.height);
-
- // initialize trot frame
- CGSize trotContainerSize = self.trotContaierView.frame.size;
- UIView *trotView = [self.trotViewArr firstObject];
- self.currentTrotView = trotView;
- CGSize trotSize = trotView.frame.size;
- if (!trotView) {
- return;
- }
- self.hidden = NO;
-
- if (self.trotingBlock) {
- self.trotingBlock();
- }
-
- if (_direction == CCZTrotDirectionLeft) {
- trotView.frame = CGRectMake(trotContainerSize.width, (_size.height - trotSize.height) / 2, trotSize.width, trotSize.height);
-
- CGFloat l = (trotContainerSize.width + trotSize.width);
- CGFloat v = l / _duration;
- self.trotingXAnimation.values = @[@(0), @(- trotContainerSize.width), @(- trotContainerSize.width), @(- l)];
- self.trotingXAnimation.keyTimes = @[@0, @(trotContainerSize.width / v / (_duration + _pause)), @(_pause / (_duration + _pause) + trotContainerSize.width / v / (_duration + _pause)), @(1)];
-
- } else if (_direction == CCZTrotDirectionRight) {
- trotView.frame = CGRectMake(- trotSize.width, (_size.height - trotSize.height) / 2, trotSize.width, trotSize.height);
-
- CGFloat l = (trotContainerSize.width + trotSize.width);
- CGFloat v = l / _duration;
- self.trotingXAnimation.values = @[@(0), @(trotContainerSize.width), @(trotContainerSize.width), @(l)];
- self.trotingXAnimation.keyTimes = @[@0, @(trotContainerSize.width / v / (_duration + _pause)), @(_pause / (_duration + _pause) + trotContainerSize.width / v / (_duration + _pause)), @(1)];
-
- } else if (_direction == CCZTrotDirectionTop) {
- trotView.frame = CGRectMake(0, trotContainerSize.height, trotSize.width, trotSize.height);
-
- CGFloat l = (trotContainerSize.height + trotSize.height);
- CGFloat v = l / _duration;
- self.trotingYAnimation.values = @[@(0), @(- ((trotContainerSize.height - trotSize.height) / 2 + trotSize.height)), @(- ((trotContainerSize.height - trotSize.height) / 2 + trotSize.height)), @(- l)];
- self.trotingYAnimation.keyTimes = @[@0, @(trotContainerSize.height / v / (_duration + _pause)), @(_pause / (_duration + _pause) + trotContainerSize.height / v / (_duration + _pause)), @(1)];
-
- } else {
- trotView.frame = CGRectMake(0, - trotSize.height, trotSize.width, trotSize.height);
-
- CGFloat l = (trotContainerSize.height + trotSize.height);
- CGFloat v = l / _duration;
- self.trotingYAnimation.values = @[@(0), @((trotContainerSize.height - trotSize.height) / 2 + trotSize.height), @((trotContainerSize.height - trotSize.height) / 2 + trotSize.height), @(l)];
- self.trotingYAnimation.keyTimes = @[@0, @(trotContainerSize.height / v / (_duration + _pause)), @(_pause / (_duration + _pause) + trotContainerSize.height / v / (_duration + _pause)), @(1)];
- }
-
- if ([trotView.layer animationForKey:@"trotingX"]) {
- [trotView.layer removeAnimationForKey:@"trotingX"];
- }
- if ([trotView.layer animationForKey:@"trotingY"]) {
- [trotView.layer removeAnimationForKey:@"trotingY"];
- }
-
- if (_direction == CCZTrotDirectionLeft || _direction == CCZTrotDirectionRight) {
- self.trotingXAnimation.removedOnCompletion = _autoTrotingRepeat;
- self.trotingXAnimation.repeatCount = _autoTrotingRepeat? CGFLOAT_MAX : 0;
- [trotView.layer addAnimation:self.trotingXAnimation forKey:@"trotingX"];
- } else {
- self.trotingYAnimation.removedOnCompletion = _autoTrotingRepeat;
- self.trotingYAnimation.repeatCount = _autoTrotingRepeat? CGFLOAT_MAX : 0;
- [trotView.layer addAnimation:self.trotingYAnimation forKey:@"trotingY"];
- }
- }
- - (CAKeyframeAnimation *)trotingXAnimation {
- if (!_trotingXAnimation) {
- _trotingXAnimation = [CAKeyframeAnimation animation];
- _trotingXAnimation.keyPath = @"transform.translation.x";
- _trotingXAnimation.delegate = self;
- _trotingXAnimation.duration = _duration;
- _trotingXAnimation.fillMode = kCAFillModeForwards;
- _trotingXAnimation.removedOnCompletion = NO;
- }
- return _trotingXAnimation;
- }
- - (CAKeyframeAnimation *)trotingYAnimation {
- if (!_trotingYAnimation) {
- _trotingYAnimation = [CAKeyframeAnimation animation];
- _trotingYAnimation.keyPath = @"transform.translation.y";
- _trotingYAnimation.delegate = self;
- _trotingYAnimation.duration = _duration;
- _trotingYAnimation.fillMode = kCAFillModeForwards;
- _trotingYAnimation.removedOnCompletion = NO;
- }
- return _trotingYAnimation;
- }
- #pragma mark -- public
- - (void)addTrotView:(UIView *)trotView {
- if (self.currentTrotView) {
- [self.trotViewArr removeObject:self.trotViewArr.firstObject];
- [self.currentTrotView removeFromSuperview];
- }
-
- [self.trotViewArr addObject:trotView];
- [self.trotContaierView addSubview:trotView];
-
- if (!_isTroting) {
- [self setNeedsLayout];
- }
- }
- - (void)trotingStop:(void (^)())stopBlock {
- if (stopBlock) {
- self.stopBlock = stopBlock;
- }
- }
- - (void)trotingStart:(void (^)())startBlcok {
- if (startBlcok) {
- self.startBlock = startBlcok;
- }
- }
- - (void)troting:(void (^)())trotingBlock {
- if (trotingBlock) {
- self.trotingBlock = trotingBlock;
- }
- }
- - (void)updateTroting {
- [self setNeedsLayout];
- }
- #pragma mark -- Set
- - (void)setBackgroundImage:(UIImage *)backgroundImage {
- _backgroundImage = backgroundImage;
-
- self.backgroundImageView.image = backgroundImage;
- }
- - (void)setLeftView:(UIView *)leftView {
- _leftView = leftView;
-
- [self addSubview:leftView];
- }
- - (void)setRightView:(UIView *)rightView {
- _rightView = rightView;
-
- [self addSubview:_rightView];
- }
- - (void)setDuration:(NSTimeInterval)duration {
- _duration = duration;
-
- self.trotingXAnimation.duration = duration;
- }
- - (void)setHideWhenStopTroting:(BOOL)hideWhenStopTroting {
- _hideWhenStopTroting = hideWhenStopTroting;
- self.hidden = hideWhenStopTroting;
- }
- #pragma mark -- Animation delegate
- - (void)animationDidStart:(CAAnimation *)anim {
- _isTroting = YES;
-
- if (self.startBlock) {
- self.startBlock();
- }
- }
- - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
- _isTroting = NO;
-
- self.hidden = self.hideWhenStopTroting;
-
- if (self.stopBlock) {
- self.stopBlock();
- }
- }
- @end
|