效果图
思路
整体上我们使用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.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.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.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; }]; } }); }
demo: link
到此这篇关于ios 实现类似抖音滚动效果的文章就介绍到这了,更多相关ios 抖音滚动内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论