// // ShoesCarouselView.m // Unity-iPhone // // Created by duowan123 on 2021/8/31. // #import "ShoesCarouselView.h" #import "ShoesCollectionCell.h" #import "TXCarouselViewLayout.h" #import "ShoesPeripheralMolde.h" #import #define itemHight 1 //当前 carousel 状态 @interface CarouselCurrentState : NSObject @property (nonatomic, assign) BOOL isOverturnState; //是否进入翻转状态 @property (nonatomic, assign) BOOL isDragState; //是否处于拖动状态 @property (nonatomic, assign) BOOL isDidScroll; //是否处于滑动状态 @property (nonatomic, assign) BOOL isCenter; //是否处于回到正中状态 @property (nonatomic, assign) BOOL isRestrict; //是否处于限制重力感应 @property (nonatomic, assign) CGFloat lastCarouselPoint;//上一个lastPoint @end @implementation CarouselCurrentState @end typedef void (^OpenAccelerometerUpdatesBlock)(CGFloat value); typedef void (^OpenGyroUpdatesBlock)(CGFloat value); @interface ShoesCarouselView ()< UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate, UIScrollViewDelegate > @property (nonatomic, strong) TXCarouselViewLayout *carouselViewLayout; @property (nonatomic, strong) CarouselCurrentState *currentState;//当前 carousel 状态 @property (nonatomic, strong) UIScrollView *superScrollView; @property (nonatomic, strong) UICollectionView *collectionView; @property (nonatomic, assign) CGFloat lasttimePoint; @property (nonatomic, assign) CGFloat gyrValue;//加速计值 @property (nonatomic, assign) CGSize carouselSize; @property (nonatomic, assign)CGFloat lastContentOffsetY; @property (nonatomic, assign) CGFloat cIndex; @property (nonatomic, assign) BOOL turnLeft;//滑动方向 @property (nonatomic, strong) NSMutableArray *modelArray; @end @implementation ShoesCarouselView #pragma mark - 生命周期 - (instancetype)initWithCoder:(NSCoder *)coder{ self = [super initWithCoder:coder]; if (self){ self.currentState = [[CarouselCurrentState alloc]init]; self.currentState.isOverturnState = NO; self.currentState.isDragState = NO; self.currentState.isDidScroll = NO; self.currentState.isCenter = NO; self.currentState.isRestrict = NO; self.userInteractionEnabled = NO; self.collectionView.scrollEnabled = NO; } return self; } // -(void)layoutSubviews{ NSLog(@"layoutSubviewslayoutSubviewslayoutSubviewslayoutSubviews"); self.carouselSize = self.frame.size; [self createCollectionView]; [self.collectionView reloadData]; [self.collectionView layoutIfNeeded]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self setpoint]; }); NSLog(@"这里运行一次"); //监听滑动结束的状态 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getNotificationAction:) name:@"ThisIsANoticafication" object:nil]; } // -(void)setpoint{ NSLog(@"setpoint"); [self.collectionView setContentOffset:CGPointMake(0, self.collectionView.contentOffset.y) animated:NO]; [self.collectionView setContentOffset:CGPointMake(0+((self.modelArray.count/2)*(self.carouselSize.height*itemHight)), self.collectionView.contentOffset.y) animated:NO]; self.currentState.lastCarouselPoint = 0; [self setSlideEnd]; } #pragma mark - loadData -(void)setArrayData:(NSArray *)array{ if (array.count<=0){ return; } if (array.count == self.modelArray.count) {//没有新的数据源不刷新 return; } [self.modelArray removeAllObjects]; [self.modelArray addObjectsFromArray:array]; [self.collectionView reloadData]; [self.collectionView layoutIfNeeded]; // 当只有一个数据源的时候 让cell滑到正中间 if (array.count==1){ // NSLog(@"设备列表只有一个数据源"); _cIndex = 0; [self testAction]; }else{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if (array.count>=5){ }else{ [self setpoint]; } }); } // 当只有两个数据源的时候 添加手势 防止collectionView数据少 没有占满屏幕 时候滑不动的BUG if (array.count>=2){ UISwipeGestureRecognizer * left = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeFrom:)]; [left setDirection:(UISwipeGestureRecognizerDirectionLeft)]; [self.collectionView addGestureRecognizer:left]; UISwipeGestureRecognizer * right = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeFrom:)]; [right setDirection:(UISwipeGestureRecognizerDirectionRight)]; [self.collectionView addGestureRecognizer:right]; } self.collectionView.scrollEnabled = NO; } #pragma mark -- UISwipeGestureRecognizer - (void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer{ if(recognizer.direction == UISwipeGestureRecognizerDirectionLeft){ [self yw_gotoNext:1]; } if(recognizer.direction == UISwipeGestureRecognizerDirectionRight){ [self yw_gotoNext:-1]; } } #pragma mark -- scrollView delegate -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ NSLog(@"scrollViewWillBeginDragging"); self.lastContentOffsetY = scrollView.contentOffset.x; } -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ // NSLog(@"scrollViewDidScroll"); if (scrollView.contentOffset.x < self.lastContentOffsetY){ // NSLog(@"左左"); self.turnLeft = YES; }else if (scrollView.contentOffset.x > self.lastContentOffsetY){ // NSLog(@"右右"); self.turnLeft = NO; } } #pragma mark -- collectionView delegate - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ // NSLog(@"self.modelArray.count - %ld",self.modelArray.count); return self.modelArray.count; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ ShoesCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ShoesCollectionCell" forIndexPath:indexPath]; ShoesPeripheralMolde * model = self.modelArray[indexPath.row]; [cell setCarouselCellModel:model]; __weak typeof(self) weakSelf = self; //单击cell 滚到cell位置 cell.tapGestureBlock = ^(NSInteger i){ if (i==_cIndex) { NSLog(@"didSelectItemAtIndexPath 点击的 是 当前"); _cIndex = i; if ([self.delegate respondsToSelector:@selector(connectDevice:)]){ [self.delegate connectDevice:model.peripheral]; } }else{ NSLog(@"didSelectItemAtIndexPath 点击的 不是 当前"); _cIndex = i; [weakSelf testAction]; } }; //默认选中 [self jugeSelected]; return cell; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ // NSLog(@"选中了 ==== %ld",(long)indexPath.row); ShoesCollectionCell * cell = (ShoesCollectionCell*)[self.collectionView cellForItemAtIndexPath:indexPath]; cell.cusSelected = YES; //将当前滚动到的cell->蓝牙 回调给SearchDeviceViewController ShoesPeripheralMolde * model = self.modelArray[indexPath.row]; if ([self.delegate respondsToSelector:@selector(setCurrentperipheral:)]){ [self.delegate setCurrentperipheral:model.peripheral]; } } - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{ // NSLog(@"未选中 ==== %ld",(long)indexPath.row); ShoesCollectionCell * cell = (ShoesCollectionCell*)[self.collectionView cellForItemAtIndexPath:indexPath]; cell.cusSelected = NO; } #pragma mark - privately method /** 回到屏幕正中间 */ -(void)setSlideEnd{ NSLog(@"setSlideEnd"); CGPoint collectionViewPoint = self.collectionView.contentOffset; if ( self.currentState.lastCarouselPoint == collectionViewPoint.x||self.currentState.isDragState){ return; } CGFloat viewHeight = CGRectGetWidth(self.collectionView.frame); CGFloat itemHeight = self.carouselSize.height*itemHight; CGFloat index = roundf((self.collectionView.contentOffset.x+ viewHeight / 2 - itemHeight / 2) /itemHeight)-1; // NSLog(@"setSlideEnd:x[%f]----y[%f]---index[%f]",collectionViewPoint.x,collectionViewPoint.y,index); collectionViewPoint.x = itemHeight * index + itemHeight / 2 - viewHeight / 2; [self.collectionView setContentOffset:CGPointMake(collectionViewPoint.x, collectionViewPoint.y) animated:YES]; self.currentState.lastCarouselPoint = self.collectionView.contentOffset.x; self.currentState.isDidScroll = YES; _cIndex = index; // NSLog(@"setSlideEnd:x[%f]----y[%f]---index[%f]",collectionViewPoint.x,collectionViewPoint.y,index); [self jugeSelected]; } #pragma mark yw add 限制点击事件 - (void)yw_gotoNext:(NSInteger)index{ NSLog(@"yw_gotoNext:(NSInteger)index = %d %ld",(int)_cIndex,(long)index); if ((int)_cIndex<1 && index == -1){//滑到最左边 return; }else if ((int)_cIndex>self.modelArray.count-2 && index == 1){//滑到最右边 return; }else{ _cIndex = _cIndex + index; [self testAction]; } } //setContentOffset到对应位置 - (void)testAction{ NSLog(@"testAction"); CGFloat viewHeight = CGRectGetWidth(self.collectionView.frame); CGFloat itemHeight = self.carouselSize.height*itemHight; CGFloat offsetX = (_cIndex + (itemHeight/2)/itemHeight - (viewHeight/2)/itemHeight)*itemHeight; // NSLog(@"testAction:%f----_cIndex:%f",offsetX,_cIndex); [self.collectionView setContentOffset:CGPointMake(offsetX, 0) animated:YES]; [self jugeSelected]; } #pragma mark leon add - (void)getNotificationAction:(NSNotification *)notification{ NSDictionary * infoDic = [notification object]; // 这样就得到了我们在发送通知时候传入的字典了 NSNumber * number = infoDic[@"parameter"]; NSInteger i = [number integerValue]; NSLog(@"通知 number ==== %@ _cIndex = %f self.modelArray.count = %lu",number,_cIndex,(unsigned long)self.modelArray.count); _cIndex = i; [self endScroll]; if (i==1&&self.turnLeft==YES){ NSLog(@"滑到最左边"); _cIndex = 0; [self endScroll]; } if (i==self.modelArray.count-2&&self.turnLeft==NO){ NSLog(@"滑到最右边"); _cIndex = self.modelArray.count-1; [self endScroll]; } } // -(void)endScroll{ NSLog(@"endScroll"); __weak typeof(self)WeakSelf = self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ CGFloat viewHeight = CGRectGetWidth(self.collectionView.frame); CGFloat itemHeight = self.carouselSize.height*itemHight; CGFloat offsetX = (_cIndex + (itemHeight/2)/itemHeight - (viewHeight/2)/itemHeight)*itemHeight; //滚动到对应位置 [WeakSelf.collectionView setContentOffset:CGPointMake(offsetX, 0) animated:YES]; //当前选中的是哪个 [WeakSelf jugeSelected]; }); } //判断哪个cell是选中的 -(void)jugeSelected{ NSLog(@"jugeSelected (NSInteger)_cIndex = %ld",(NSInteger)_cIndex); //判断哪个是选中的 for (NSInteger i =0; i