iOS 实现类似抖音翻页滚动效果

这里是效果图

参考抖音的滚动效果,需要我们在结束拖动的时候,动画设置偏移量

这里有一个注意点,由于我们是在拖动结束的时候,手动改变tableview的偏移量,

改变了tableView 自身原有的的滚动效果,所以我们

需要讲tableView 的frame的高度设置为三个cell的高度,然后,设置contentInset

的顶部和底部都是cell的高度,否则会导致我们滚动的过程中cell还没有加载出来

,展示成一片空白的效果

直接上代码

复制代码
//
//  DouyinScrollViewController.m
//  TEXT
//
//  Created by mac on 2024/4/28.
//  Copyright © 2024 刘博. All rights reserved.
//

#import "DouyinScrollViewController.h"
#import "DouyinScrollTableViewCell.h"

static CGFloat const height = 700;

@interface DouyinScrollViewController () <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) UITableView *tableView;

@property (nonatomic, assign) NSInteger currentIndex;

@property (nonatomic, assign) CGFloat velocity;

@property (nonatomic, strong) NSMutableArray *colorArray;

@end

@implementation DouyinScrollViewController

- (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 height;
}

#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;
        NSLog(@"哈哈哈哈获取停止拖动时候的速度%f", self.velocity);
        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 --;   //向上滑动索引递减
        }
        [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 mark - lazy load

- (UITableView *)tableView
{
    if (!_tableView) {
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 60 - height, CGRectGetWidth(self.view.bounds), height * 3) style:UITableViewStylePlain];
        [_tableView registerClass:[DouyinScrollTableViewCell class] forCellReuseIdentifier:NSStringFromClass([DouyinScrollTableViewCell class])];
        _tableView.rowHeight = height;
        _tableView.contentInset = UIEdgeInsetsMake(height , 0, height, 0);
        _tableView.estimatedRowHeight = height;
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.backgroundColor = [UIColor redColor];
        _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        _tableView.separatorInset = UIEdgeInsetsZero;
    }
    return _tableView;
}

/*
 #pragma mark - Navigation
 
 // In a storyboard-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
 // Get the new view controller using [segue destinationViewController].
 // Pass the selected object to the new view controller.
 }
 */

@end
相关推荐
叽哥6 小时前
Flutter Riverpod上手指南
android·flutter·ios
用户091 天前
SwiftUI Charts 函数绘图完全指南
ios·swiftui·swift
YungFan1 天前
iOS26适配指南之UIColor
ios·swift
权咚2 天前
阿权的开发经验小集
git·ios·xcode
用户092 天前
TipKit与CloudKit同步完全指南
ios·swift
小溪彼岸2 天前
macOS自带截图命令ScreenCapture
macos
法的空间2 天前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
2501_915918412 天前
iOS 上架全流程指南 iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传 ipa 与审核实战经验分享
android·ios·小程序·uni-app·cocoa·iphone·webview
TESmart碲视2 天前
Mac 真正多显示器支持:TESmart USB-C KVM(搭载 DisplayLink 技术)如何实现
macos·计算机外设·电脑
00后程序员张2 天前
iOS App 混淆与加固对比 源码混淆与ipa文件混淆的区别、iOS代码保护与应用安全场景最佳实践
android·安全·ios·小程序·uni-app·iphone·webview