Commit 7921ebe1 authored by lufei's avatar lufei

fix:

1.修复定时滚动时,存在偏移误差,原因是UIScrollView的setContentOffset动画时长大于0.3s,重置页面延时执行时间为0.3s,产生冲突
2.优化代码,pageWillShow调用时机修改
3.删除冗余代码
parent d85a8446
...@@ -70,6 +70,8 @@ typedef void(^DZXCarouselPageWillShowBlock)(NSInteger index, id data); ...@@ -70,6 +70,8 @@ typedef void(^DZXCarouselPageWillShowBlock)(NSInteger index, id data);
@property (nonatomic, copy) NSString *propertyName; @property (nonatomic, copy) NSString *propertyName;
/// 自动滚动 /// 自动滚动
@property (nonatomic, assign) BOOL autoScroll; @property (nonatomic, assign) BOOL autoScroll;
/// 允许滑动
@property(nonatomic, assign) BOOL allowSlide;
/// pageControl /// pageControl
@property (nonatomic, assign) BOOL showPageControl; @property (nonatomic, assign) BOOL showPageControl;
/// pageControl普通状态的图片 /// pageControl普通状态的图片
...@@ -103,7 +105,7 @@ typedef void(^DZXCarouselPageWillShowBlock)(NSInteger index, id data); ...@@ -103,7 +105,7 @@ typedef void(^DZXCarouselPageWillShowBlock)(NSInteger index, id data);
/// @param frame frame /// @param frame frame
/// @param configBlock 配置回调 /// @param configBlock 配置回调
/// @param tapBlock 点击回调 /// @param tapBlock 点击回调
/// @param pageShowBlock 页面将展示回调 /// @param pageWillShowBlock 页面将展示回调
/// @param pageShowBlock 页面展示回调 /// @param pageShowBlock 页面展示回调
- (instancetype)initWithFrame:(CGRect)frame - (instancetype)initWithFrame:(CGRect)frame
configBlock:(DZXCarouselConfigBlock)configBlock configBlock:(DZXCarouselConfigBlock)configBlock
......
...@@ -30,6 +30,11 @@ ...@@ -30,6 +30,11 @@
// others // others
static double const kResetTime = 0.35;//页面重置时间
static double const kMargin = 50;//偏移间隔
static BOOL isScrolling = NO;
@implementation DZXCarouselConfig @implementation DZXCarouselConfig
- (instancetype)init { - (instancetype)init {
...@@ -38,13 +43,14 @@ ...@@ -38,13 +43,14 @@
self.theme = DZXCarouselThemeHorizontal; self.theme = DZXCarouselThemeHorizontal;
self.autoScroll = NO; self.autoScroll = NO;
self.showPageControl = NO; self.showPageControl = NO;
self.padding = UIEdgeInsetsZero; self.padding = UIEdgeInsetsZero
self.cornerRadius = 2.0f; self.cornerRadius = 2.0f;
self.pageControlTheme = DZXCarouselPageControlThemeCenter; self.pageControlTheme = DZXCarouselPageControlThemeCenter;
self.pageControlLeftRightMargin = 8.0f; self.pageControlLeftRightMargin = 8.0f;
self.pageControlBottomMargin = 8.0f; self.pageControlBottomMargin = 8.0f;
self.pageIndicatorSpaing = 10.0f; self.pageIndicatorSpaing = 10.0f;
self.pageIndicatorSize = CGSizeMake(6, 6); self.pageIndicatorSize = CGSizeMake(6.0, 6.0);
self.allowSlide = YES;
NSInteger scale = [[UIScreen mainScreen] scale]; NSInteger scale = [[UIScreen mainScreen] scale];
NSBundle *bannerBundle = [NSBundle bundleForClass:DZXCarouselView.class]; NSBundle *bannerBundle = [NSBundle bundleForClass:DZXCarouselView.class];
...@@ -57,10 +63,7 @@ ...@@ -57,10 +63,7 @@
@end @end
@interface DZXCarouselView ()<UIScrollViewDelegate> { @interface DZXCarouselView ()<UIScrollViewDelegate> {
CGPoint _startContentOffset; BOOL _isLast;//YES:向上一页面滚;NO:向下一页面滚
CGPoint _willEndContentOffset;
CGPoint _endContentOffset;
BOOL _isLast;
} }
/// 配置 /// 配置
@property(nonatomic, strong) DZXCarouselConfig *carouselConfig; @property(nonatomic, strong) DZXCarouselConfig *carouselConfig;
...@@ -126,15 +129,15 @@ ...@@ -126,15 +129,15 @@
} }
- (void)layoutSubviews { - (void)layoutSubviews {
self.scrollView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); self.scrollView.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
[self updateSubViewFrames]; [self updateSubViewFrames];
if (_carouselConfig.theme == DZXCarouselThemeVertical) { if (_carouselConfig.theme == DZXCarouselThemeVertical) {
_scrollView.contentOffset = CGPointMake(0, self.frame.size.height); _scrollView.contentSize = CGSizeMake(self.bounds.size.width, self.bounds.size.height*3.0);
_scrollView.contentSize = CGSizeMake(self.frame.size.width, self.frame.size.height*3); _scrollView.contentOffset = CGPointMake(0, self.bounds.size.height);
}else{ }else{
_scrollView.contentOffset = CGPointMake(self.frame.size.width, 0); _scrollView.contentSize = CGSizeMake(self.bounds.size.width*3.0, self.bounds.size.height);
_scrollView.contentSize = CGSizeMake(self.frame.size.width*3, self.frame.size.height); _scrollView.contentOffset = CGPointMake(self.bounds.size.width, 0);
} }
} }
#pragma mark - Public Methods #pragma mark - Public Methods
...@@ -148,15 +151,14 @@ ...@@ -148,15 +151,14 @@
- (void)timerStart { - (void)timerStart {
if (_carouselConfig.autoScroll && _dataArr.count > 1) { if (_carouselConfig.autoScroll && _dataArr.count > 1) {
[self timerStop]; [self timerStop];
self.timer = [NSTimer scheduledTimerWithTimeInterval:_carouselConfig.timeInterval target:self selector:@selector(timerAction:) userInfo:nil repeats:YES]; self.timer = [NSTimer scheduledTimerWithTimeInterval:_carouselConfig.timeInterval target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode]; [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
} }
} }
- (void)updateCurrentIndex:(NSInteger)currentIndex { - (void)updateCurrentIndex:(NSInteger)currentIndex {
if (currentIndex >= _dataArr.count || currentIndex < 0) { if (_currentIndex < 0 || _currentIndex >= _dataArr.count) return;
return;
}
[self timerStop]; [self timerStop];
if (_pageWillShowBlock) { if (_pageWillShowBlock) {
...@@ -175,23 +177,17 @@ ...@@ -175,23 +177,17 @@
Class className = NSClassFromString(_carouselConfig.subViewClass); Class className = NSClassFromString(_carouselConfig.subViewClass);
self.lastV = [[className alloc] init]; self.lastV = [[className alloc] init];
if (_carouselConfig.theme == DZXCarouselThemeVertical) {
self.currentV = [[className alloc] init];
self.nextV = [[className alloc] init];
}else{
self.currentV = [[className alloc] init]; self.currentV = [[className alloc] init];
self.nextV = [[className alloc] init]; self.nextV = [[className alloc] init];
}
[self updateSubViewFrames];
[_scrollView addSubview:_lastV]; [_scrollView addSubview:_lastV];
[_scrollView addSubview:_currentV]; [_scrollView addSubview:_currentV];
[_scrollView addSubview:_nextV];
[self updateSubViewFrames];
UITapGestureRecognizer *tapGes = [UITapGestureRecognizer.alloc initWithTarget:self action:@selector(tapCurrentView)]; UITapGestureRecognizer *tapGes = [UITapGestureRecognizer.alloc initWithTarget:self action:@selector(tapCurrentView)];
[_currentV addGestureRecognizer:tapGes]; [_currentV addGestureRecognizer:tapGes];
[_scrollView addSubview:_nextV];
_lastV.layer.cornerRadius = _carouselConfig.cornerRadius; _lastV.layer.cornerRadius = _carouselConfig.cornerRadius;
_lastV.layer.masksToBounds = YES; _lastV.layer.masksToBounds = YES;
...@@ -228,13 +224,13 @@ ...@@ -228,13 +224,13 @@
} }
- (void)updateSubViewFrames { - (void)updateSubViewFrames {
_lastV.frame = CGRectMake(_carouselConfig.padding.left, _carouselConfig.padding.top,self.frame.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.frame.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom); _lastV.frame = CGRectMake(_carouselConfig.padding.left, _carouselConfig.padding.top,self.bounds.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.bounds.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom);
if (_carouselConfig.theme == DZXCarouselThemeVertical) { if (_carouselConfig.theme == DZXCarouselThemeVertical) {
_currentV.frame = CGRectMake(_carouselConfig.padding.left, self.frame.size.height+_carouselConfig.padding.top,self.frame.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.frame.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom); _currentV.frame = CGRectMake(_carouselConfig.padding.left, self.bounds.size.height+_carouselConfig.padding.top,self.bounds.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.bounds.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom);
_nextV.frame = CGRectMake(_carouselConfig.padding.left, self.frame.size.height*2+_carouselConfig.padding.top,self.frame.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.frame.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom); _nextV.frame = CGRectMake(_carouselConfig.padding.left, self.bounds.size.height*2+_carouselConfig.padding.top,self.bounds.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.bounds.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom);
}else{ }else{
_currentV.frame = CGRectMake(self.frame.size.width+_carouselConfig.padding.left, _carouselConfig.padding.top,self.frame.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.frame.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom); _currentV.frame = CGRectMake(self.bounds.size.width+_carouselConfig.padding.left, _carouselConfig.padding.top,self.bounds.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.bounds.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom);
_nextV.frame = CGRectMake(self.frame.size.width*2+_carouselConfig.padding.left, _carouselConfig.padding.top,self.frame.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.frame.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom); _nextV.frame = CGRectMake(self.bounds.size.width*2+_carouselConfig.padding.left, _carouselConfig.padding.top,self.bounds.size.width-_carouselConfig.padding.left-_carouselConfig.padding.right, self.bounds.size.height-_carouselConfig.padding.top-_carouselConfig.padding.bottom);
} }
} }
...@@ -257,9 +253,9 @@ ...@@ -257,9 +253,9 @@
[self addProperty:_dataArr[(_currentIndex+1)%_dataArr.count] toObj:_nextV]; [self addProperty:_dataArr[(_currentIndex+1)%_dataArr.count] toObj:_nextV];
if (_carouselConfig.theme == DZXCarouselThemeVertical) { if (_carouselConfig.theme == DZXCarouselThemeVertical) {
[_scrollView setContentOffset:CGPointMake(0, self.frame.size.height)]; [_scrollView setContentOffset:CGPointMake(0, self.bounds.size.height)];
}else{ }else{
[_scrollView setContentOffset:CGPointMake(self.frame.size.width, 0)]; [_scrollView setContentOffset:CGPointMake(self.bounds.size.width, 0)];
} }
_pageControl.currentPage = _currentIndex; _pageControl.currentPage = _currentIndex;
...@@ -273,70 +269,99 @@ ...@@ -273,70 +269,99 @@
} }
#pragma mark - KVO Methods #pragma mark - KVO Methods
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
_startContentOffset = scrollView.contentOffset; //手势拖拽触发-关闭定时器
[self timerStop]; [self timerStop];
} }
//滑动偏移落在间隔区间内,置NO;
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (_carouselConfig.theme == DZXCarouselThemeVertical) {
if (scrollView.contentOffset.y < self.bounds.size.height-kMargin) {
//从上向下
if (isScrolling) return;
[self pageWillShow:YES];
isScrolling = YES;
}else if(scrollView.contentOffset.y > self.bounds.size.width+kMargin){
//从下向上
if (isScrolling) return;
[self pageWillShow:NO];
isScrolling = YES;
}else{
isScrolling = NO;
}
}else{
if (scrollView.contentOffset.x < self.bounds.size.width-kMargin) {
//从左向右
if (isScrolling) return;
[self pageWillShow:YES];
isScrolling = YES;
}else if(scrollView.contentOffset.x > self.bounds.size.width+kMargin){
//从右向左
if (isScrolling) return;
[self pageWillShow:NO];
isScrolling = YES;
}else{
isScrolling = NO;
}
}
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
_willEndContentOffset = scrollView.contentOffset;
} }
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
_endContentOffset = scrollView.contentOffset;
if (_carouselConfig.theme == DZXCarouselThemeVertical) { if (_carouselConfig.theme == DZXCarouselThemeVertical) {
if (_endContentOffset.y < _willEndContentOffset.y && _willEndContentOffset.y < _startContentOffset.y) { if (scrollView.contentOffset.y < self.bounds.size.height) {
//画面从上往下移动,上一页 //画面从上往下移动,上一页
_isLast = YES; _isLast = YES;
} else if (_endContentOffset.y > _willEndContentOffset.y && _willEndContentOffset.y > _startContentOffset.y) { [NSTimer scheduledTimerWithTimeInterval:kResetTime target:self selector:@selector(scroll) userInfo:nil repeats:NO];
}else if (scrollView.contentOffset.y > self.bounds.size.height) {
//画面从下往上移动,下一页 //画面从下往上移动,下一页
_isLast = NO; _isLast = NO;
[NSTimer scheduledTimerWithTimeInterval:kResetTime target:self selector:@selector(scroll) userInfo:nil repeats:NO];
}else {
//不变
} }
}else{ }else{
if (_endContentOffset.x < _willEndContentOffset.x && _willEndContentOffset.x < _startContentOffset.x) { if (scrollView.contentOffset.x < self.bounds.size.width) {
//画面从左往右移动,上一页 //画面从左往右移动,上一页
_isLast = YES; _isLast = YES;
} else if (_endContentOffset.x > _willEndContentOffset.x && _willEndContentOffset.x > _startContentOffset.x) { [NSTimer scheduledTimerWithTimeInterval:kResetTime target:self selector:@selector(scroll) userInfo:nil repeats:NO];
}else if (scrollView.contentOffset.x > self.bounds.size.width) {
//画面从右往左移动,下一页 //画面从右往左移动,下一页
_isLast = NO; _isLast = NO;
[NSTimer scheduledTimerWithTimeInterval:kResetTime target:self selector:@selector(scroll) userInfo:nil repeats:NO];
}else {
//不变
} }
} }
[self timerAction:_isLast];
[self timerStart]; [self timerStart];
} }
#pragma mark - Notification Methods #pragma mark - Notification Methods
#pragma mark - Target Methods #pragma mark - Target Methods
-(void)timerAction:(BOOL)isLast { -(void)timerAction {
[self pageWillShow:isLast];
__weak __typeof(self)weakSelf = self; __weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
__strong __typeof(weakSelf)strongSelf = weakSelf; __strong __typeof(weakSelf)strongSelf = weakSelf;
if (isLast) {
if (strongSelf.carouselConfig.theme == DZXCarouselThemeVertical) { if (strongSelf.carouselConfig.theme == DZXCarouselThemeVertical) {
[strongSelf.scrollView setContentOffset:CGPointMake(0, 0) animated:YES]; [strongSelf.scrollView setContentOffset:CGPointMake(0, self.bounds.size.height*2.0) animated:YES];
}else{ }else{
[strongSelf.scrollView setContentOffset:CGPointMake(0, 0) animated:YES]; [strongSelf.scrollView setContentOffset:CGPointMake(self.bounds.size.width*2.0, 0) animated:YES];
}
}else{
if (strongSelf.carouselConfig.theme == DZXCarouselThemeVertical) {
[strongSelf.scrollView setContentOffset:CGPointMake(0, self.frame.size.height*2) animated:YES];
}else{
[strongSelf.scrollView setContentOffset:CGPointMake(self.frame.size.width*2, 0) animated:YES];
}
} }
}); });
//动画过后重置位置 //动画过后重置位置
[NSTimer scheduledTimerWithTimeInterval:.3 target:self selector:@selector(scroll) userInfo:nil repeats:NO]; [NSTimer scheduledTimerWithTimeInterval:kResetTime target:self selector:@selector(scroll) userInfo:nil repeats:NO];
} }
#pragma mark - Action #pragma mark - Action
//将要显示 //将要显示
- (void)pageWillShow:(BOOL)isLast { - (void)pageWillShow:(BOOL)isLast {
if (_currentIndex < 0 || _currentIndex >= _dataArr.count) return;
NSInteger willShowIndex; NSInteger willShowIndex;
if (_isLast) { if (isLast) {
willShowIndex = (_currentIndex - 1)%_dataArr.count; willShowIndex = (_currentIndex - 1)%_dataArr.count;
}else{ }else{
willShowIndex = (_currentIndex + 1)%_dataArr.count; willShowIndex = (_currentIndex + 1)%_dataArr.count;
...@@ -347,12 +372,14 @@ ...@@ -347,12 +372,14 @@
} }
//已显示 //已显示
- (void)pageShow { - (void)pageShow {
if (_currentIndex < 0 || _currentIndex >= _dataArr.count) return;
if (_pageShowBlock) { if (_pageShowBlock) {
_pageShowBlock(_currentIndex,_dataArr[_currentIndex]); _pageShowBlock(_currentIndex,_dataArr[_currentIndex]);
} }
} }
///点击 ///点击
- (void)tapCurrentView { - (void)tapCurrentView {
if (_currentIndex < 0 || _currentIndex >= _dataArr.count) return;
if (self.tapBlock) { if (self.tapBlock) {
self.tapBlock(_currentIndex, self.dataArr[_currentIndex]); self.tapBlock(_currentIndex, self.dataArr[_currentIndex]);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment