按钮点击 / collectionView滚动切换 / pickerView的互相联动

需求:中间红色框为横向滚动的collectionView(前一场/后一场的可用:当前第0场,前一场不可用;当前最后一场,后一场不可用)。

1. 点击前一场/后一场, collectionView滚动到对应位置,中间显示当前选择时间,控制前一场/后一场是否可用
2. 滚动collectionView,控制前一场/后一场是否可用,中间显示当前选择时间
3. 选择pickerView,collectionView滚动到对应位置,控制前一场/后一场是否可用,中间显示当前选择时间

效果.jpg
点击时间,弹出pickerView与遮罩.jpg

1. 设置默认显示:

- (void)viewDidLoad {
    [super viewDidLoad];
    // 默认显示第最后一场,此时不能加collectionView的滚动动画
    _currentScreening = self.movieHallSeatModels.count-1;
    [self showDataWithCurrentScreening:_currentScreening animated:NO];
}

2. 点击前一场:

- (void)didClickLastFilmBtn {
    
    if (_currentScreening == 0) return;

    _currentScreening--;
    [self showDataWithCurrentScreening:_currentScreening animated:YES];
}

3. 点击后一场:

- (void)didClickNextFilmBtn {
    
    if (_currentScreening == self.movieHallSeatModels.count-1) return;
    
    _currentScreening++;
    [self showDataWithCurrentScreening:_currentScreening animated:YES];
}

4. 点击时间,弹出pickerView,并选中到当前场次:

- (void)didClickChooseTimeBtn {
    
    [self.view addSubview:self.maskview];
    [self.maskview addSubview:self.chooseTimeView];
    
    CGFloat y = SCREEN_HEIGHT - FYChooseTimeView_H;
    CGFloat height = FYChooseTimeView_H;
    [UIView animateWithDuration:0.3 animations:^{
        self.chooseTimeView.frame = CGRectMake(0, y, SCREEN_WIDTH, height);
    }];
    
    // pickerView显示当前选中场次
    [self.timePickerView selectRow:_currentScreening inComponent:0 animated:NO];
}

选中pickerView的代理方法 :
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    _chosenRow = row;
    _currentScreening = row;
    _chosenTimeStr = self.chooseTimes[row];
}

点击确定:
- (void)didClickConfirmTimeBtn {
    
    [self showDataWithCurrentScreening:_chosenRow animated:YES];
    [self didClickMaskviewBtn];
}

核心方法:

- (void)showDataWithCurrentScreening:(NSInteger)index animated:(BOOL)animated{
    // 设置可用
    [self isFilmBtnEnableWithButton:self.lastFilmBtn condition:0];
    [self isFilmBtnEnableWithButton:self.nextFilmBtn condition:self.movieHallSeatModels.count-1];

    // 设置显示时间,及pickView的选中
    _chosenTimeStr = self.chooseTimes[index];
    [self.chooseTimeBtn setTitle:_chosenTimeStr forState:UIControlStateNormal];
    [self.timePickerView selectRow:_currentScreening inComponent:0 animated:NO];
    
    // 滚动到指定cell
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:_currentScreening inSection:0];
    [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:animated];

}
- (void)isFilmBtnEnableWithButton:(UIButton *)button condition:(NSInteger)index{
    
    if (_currentScreening == index) {
        button.userInteractionEnabled = NO;
        button.alpha = 0.4;
    }else {
        button.userInteractionEnabled = YES;
        button.alpha = 1;
    }
}

5. 滚动collectionView,显示对应场次,且控制collectionView滚动不足半个屏幕的时候跳回到上一个,滚动超过半个屏幕跳到下一个:


- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    // 获取滚动的当前位置
    CGPoint originalTargetContentOffset = CGPointMake(targetContentOffset->x, targetContentOffset->y);
    CGPoint targetCenter = CGPointMake(originalTargetContentOffset.x + CGRectGetWidth(self.collectionView.bounds)/2, CGRectGetHeight(self.collectionView.bounds) / 2);
    NSIndexPath *indexPath = nil;
    NSInteger i = 0;
    while (indexPath == nil) {
        targetCenter = CGPointMake(originalTargetContentOffset.x + CGRectGetWidth(self.collectionView.bounds)/2 + 10*i, CGRectGetHeight(self.collectionView.bounds) / 2);
        indexPath = [self.collectionView indexPathForItemAtPoint:targetCenter];
        i++;
    }
     _currentScreening = indexPath.item;
    
    // 设置对应显示
    _chosenTimeStr = self.chooseTimes[_currentScreening];
    [self.chooseTimeBtn setTitle:_chosenTimeStr forState:UIControlStateNormal];
    [self isFilmBtnEnableWithButton:self.lastFilmBtn condition:0];
    [self isFilmBtnEnableWithButton:self.nextFilmBtn condition:self.movieHallSeatModels.count-1];
    [self.timePickerView selectRow:_currentScreening inComponent:0 animated:NO];
    
    // 调转到指定位置
    UICollectionViewLayoutAttributes *attributes = [self.collectionView.collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath];
    if (attributes) {
        *targetContentOffset = CGPointMake(attributes.center.x - CGRectGetWidth(self.collectionView.bounds)/2, originalTargetContentOffset.y);
    }
}

推荐阅读更多精彩内容