您的位置:首页 > 文旅 > 旅游 > iOS 实现类似抖音滚动效果

iOS 实现类似抖音滚动效果

2024/10/5 0:15:03 来源:https://blog.csdn.net/LIUXIAOXIAOBO/article/details/139998409  浏览:    关键词:iOS 实现类似抖音滚动效果

效果图

请添加图片描述

思路

整体上我们使用tableView实现,为了预留内容的缓冲,我们将tableView 的contentinset设置为上面一个屏幕的高度,下面一个屏幕的高度,左右为0,这样保证我们滚动过去的时候
都是准备好的内容
然后就是滑动效果的实现了,主要就是我们在scrollViewWillEndDragging方法中获取到停止拖动(手指离开)时候的速度。 在scrollViewDidEndDragging 方法中
通过translationInView方法判断当前滑动的方向,
然后刚才获取到的速度就派上用场了,当我们手指离开时候的速度大于0.4的时候,我们切换页面的临界偏移量就是8 ,否则临界偏移量就是60, 同时,通过
CGPoint translatedPoint = [scrollView.panGestureRecognizer translationInView:scrollView];判断translatedPoint.y我们可以
判断滚动的方向,判断出方向之后,
使用UIView animateWithDuration动画快速翻页

代码

//
//  ViewController.m
//  LBDouyinScroll
//
//  Created by mac on 2024/6/26.
//#import "ViewController.h"
#import "DouyinScrollTableViewCell.h"#define kScreenWidth  [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height@interface ViewController ()
@property (nonatomic, strong) UITableView *tableView;@property (nonatomic, assign) NSInteger currentIndex;@property (nonatomic, assign) CGFloat velocity;@property (nonatomic, strong) NSMutableArray *colorArray;@end@implementation ViewController- (BOOL)prefersStatusBarHidden
{return YES;
}- (void)viewDidLoad {[super viewDidLoad];[self.view addSubview:self.tableView];self.colorArray = [NSMutableArray array];for (int i = 0; i < 10; i ++) {int r = arc4random() % 255;int g = arc4random() % 255;int b = arc4random() % 255;CGFloat rr = r / 255.0;CGFloat rg = g / 255.0;CGFloat rb = b / 255.0;UIColor *color = [[UIColor alloc]initWithRed:rr green:rg blue:rb alpha:1];[self.colorArray addObject:color];}[self.tableView reloadData];// Do any additional setup after loading the view.
}#pragma mark - UITableViewDelegate, UITableViewDataSource- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{DouyinScrollTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([DouyinScrollTableViewCell class])];[cell updateWithColor:self.colorArray[indexPath.row]];//    cell.textLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row];//    cell.backgroundColor = self.colorArray[indexPath.row];//    if (!cell.contentView.backgroundColor) {//        cell.contentView.backgroundColor = self.colorArray[indexPath.row];//    }//    return cell;return cell;
}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return 10;
}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{return kScreenHeight;
}#pragma mark - scrolllVIewDelegate- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{}- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{self.velocity = velocity.y;
}- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{dispatch_async(dispatch_get_main_queue(), ^{CGPoint translatedPoint = [scrollView.panGestureRecognizer translationInView:scrollView];//UITableView禁止响应其他滑动手势scrollView.panGestureRecognizer.enabled = NO;CGFloat translateCheck = 60;if (fabs(self.velocity) > 0.4) {translateCheck = 8;}if(translatedPoint.y < -translateCheck && self.currentIndex < 10) {self.currentIndex ++;   //向下滑动索引递增}if(translatedPoint.y > translateCheck && self.currentIndex > 0) {self.currentIndex --;   //向上滑动索引递减}if (self.currentIndex == 10) {} else {[UIView animateWithDuration:0.15delay:0.0options:UIViewAnimationOptionCurveEaseOut animations:^{//UITableView滑动到指定cell[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.currentIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];} completion:^(BOOL finished) {//UITableView可以响应其他滑动手势scrollView.panGestureRecognizer.enabled = YES;}];}});
}#pragma - private- (void)animationToIndex:(NSInteger)index
{[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{self.tableView.contentOffset = CGPointMake(0, kScreenHeight * index);} completion:^(BOOL finished) {}];
}#pragma mark - lazy load- (UITableView *)tableView
{if (!_tableView) {_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, - kScreenHeight, CGRectGetWidth(self.view.bounds), kScreenHeight * 3) style:UITableViewStylePlain];[_tableView registerClass:[DouyinScrollTableViewCell class] forCellReuseIdentifier:NSStringFromClass([DouyinScrollTableViewCell class])];_tableView.rowHeight = kScreenHeight;_tableView.contentInset = UIEdgeInsetsMake(kScreenHeight , 0, kScreenHeight, 0);_tableView.estimatedRowHeight = kScreenHeight;_tableView.delegate = self;_tableView.dataSource = self;_tableView.backgroundColor = [UIColor redColor];_tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;_tableView.separatorInset = UIEdgeInsetsZero;_tableView.decelerationRate = UIScrollViewDecelerationRateFast;}return _tableView;
}@end

其中最关键的就是下面的

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{self.velocity = velocity.y;
}- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{dispatch_async(dispatch_get_main_queue(), ^{CGPoint translatedPoint = [scrollView.panGestureRecognizer translationInView:scrollView];//UITableView禁止响应其他滑动手势scrollView.panGestureRecognizer.enabled = NO;CGFloat translateCheck = 60;if (fabs(self.velocity) > 0.4) {translateCheck = 8;}if(translatedPoint.y < -translateCheck && self.currentIndex < 10) {self.currentIndex ++;   //向下滑动索引递增}if(translatedPoint.y > translateCheck && self.currentIndex > 0) {self.currentIndex --;   //向上滑动索引递减}if (self.currentIndex == 10) {} else {[UIView animateWithDuration:0.15delay:0.0options:UIViewAnimationOptionCurveEaseOut animations:^{//UITableView滑动到指定cell[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.currentIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];} completion:^(BOOL finished) {//UITableView可以响应其他滑动手势scrollView.panGestureRecognizer.enabled = YES;}];}});
}

demo: link

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com