当前位置:

首页 > 编程开发 > iOS 实现类似抖音滚动效果

iOS 实现类似抖音滚动效果

基于UITableView实现抖音式滚动效果,通过设置contentInet上下各一个屏幕高度作为缓冲,在scrollViewWillEndDragging方法获取手指离开速度,于scrollViewDidEndDragging中根据速度绝对值是否大于0.4决定切换临界偏移量(8或60点),结合手势方向判断上下滑动,最后用UIView动画快速翻页至目标cel

本文目录

    效果图

    请添加图片描述

    思路

    整体思路其实不难——直接拿tableView来撑。为了让内容有足够的缓冲空间,我们把tableView的contentInset设成上下各一个屏幕的高度,左右留0。这样在滚动时,内容其实早就准备好了,不会出现临时加载的尴尬。

    滑动效果的实现是重头戏。关键是在scrollViewWillEndDragging方法里拿到手指离开屏幕那一瞬间的速度,然后在scrollViewDidEndDragging方法里通过translationInView判断滑动的方向。

    速度这个值怎么用?很简单:当手指离开时的速度绝对值大于0.4,切换页面的临界偏移量就设成8个点;否则就放宽到60个点。方向判断靠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.15      delay:0.0    options: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.contentInsetAdjustmentBeha vior = 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.15      delay:0.0    options: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;
                }];
            }
        });
    }
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 IOS软件
    相关文章 更多
    漫蛙漫画最新网址链接进入
    漫蛙漫画最新网址链接进入

    漫蛙漫画官网全解析:资源、体验与稳定性深度评测 “漫蛙漫画最新网址是什么?”“官方的在线观看入口在哪里?”——最近,这类问题在漫画爱好者圈子里可谓不绝于耳。别急,2025年最新、最稳的官方访问途径,这就为你一一道来。 官网入口直通车:https://www.manwamh.top 平台资源覆盖广度

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。