【iOS】仿中国邮电通信手提式有线电话机营业厅首页波纹圆环

先上效果图:

ok,上一遍笔者给我们用一种形式完结了简短的支付宝首页样式。上一篇著作:https://www.jianshu.com/p/658f2aeafa64

图片 1003.gif

那篇作品里面方法有个一弊病,即是UITableView的万丈和Cell的总中度一致,也等于UITableView无法滑动,UITableViewCell的复用机制页就不起功效了。哈哈,懒人版的支付宝首页样式是足以那样变成的。

运用联通号码的意中人对此动画应该很纯熟,自从更新5.0版本后初叶产出那么些波纹的圆环,深入分析了一晃达成原理,用的东西还非常多,使小编只可以把高级中学的数学知识再温习叁遍,话说高级中学的数学知识都还给老师了,深感羞愧啊,波浪线使用的是正余弦函数:

那边就给我们讲明一种新的仿支付宝样式的办法,这种艺术只是利用八个UITableView,何况并非用三个UIScrollView嵌套,很便利並且UITableViewCell的复用机制也能够放心的行使。先上动图(哈哈哈,即便看上去和上二个体裁同样,可是的确是二种区别的代码):

图片 2d6ca7bcb0a46f21f0f04e644f0246b600c33aef1.png

图片 3仿支付宝样式.gif

正弦型函数解析式:y=Asin+b各常数值对函数图像的影响:φ:决定波形与X轴位置关系或横向移动距离ω:决定周期(最小正周期T=2π/∣ω∣)A:决定峰值(即纵向拉伸压缩的倍数)b:表示波形在Y轴的位置关系或纵向移动距离

接一下是层级关系图片:

大家想绘制波纹图形,将要用正弦型函数分析式:y=Asin+b获取y坐标,将圆环放入坐标系中,并整合大家的无绳电话机显示屏的坐标;圆环的直径相当于一个周期2M_PI,其y坐标为sinf(2
* M_PI / 直径 * x + self.offset * M_PI * 2 / 直径)代码如下:

图片 41.jpg图片 52.jpg

设置需显示的数据- setTitle:(NSString *)title num:(NSString *)num des:(NSString *)des recharge:(NSString *)recharge{ self.firstLayer.fillColor = self.firstColor.CGColor; self.secondLayer.fillColor = self.secondColor.CGColor; [self setContent]; _titleL.text = title; _numL.text = num; _desL.text = des; [_rechargeB setTitle:recharge forState:UIControlStateNormal]; _height = self.bounds.size.height * (1 - self.progress); [self stopWave]; [self startWave];}

- startWave{ self.timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(waveAnimation)]; [self.timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];}

大家能够通过层级关系显著,此时任何调控器只有二个UITableView,我们在UITableView的taleViewHeaderView上增添四个开支的视图。

看看CADisplayLink你只怕会倍感觉不熟悉,CADisplayLink是三个能让大家以和显示器刷新率一样的功用将内容画到显示屏上的沙漏。当创建贰个新的CADisplayLink对象并把它增加到叁个runloop中,当CADisplayLink以特定的情势注册到runloop之后,每当显示器须要刷新的时候,runloop就能够调用CADisplayLink绑定的target的selector,那时target能够读到CADisplayLink的每一次调用的小时戳,用来希图下一帧呈现要求的数码。绘制波纹路线的代码:

// 设置头部视图 self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.lyf_width, kHeaderHeight)]; // 将支付的视图添加在头部视图上面 [self.headerView addSubview:self.payView]; self.tableHeaderView = self.headerView;
- waveAnimation{ CGFloat waveHeight = self.waveRange; if (self.progress == 0.0f || self.progress == 1.0f) { waveHeight = 0.f; } self.offset += self.rate; //第一条波纹路径 CGMutablePathRef pathRef = CGPathCreateMutable(); CGFloat startOffY = waveHeight * sinf(self.offset * M_PI * 2 / self.bgview.bounds.size.width); CGFloat orignOffY = 0.0; CGPathMoveToPoint(pathRef, NULL, 0, startOffY); for (CGFloat i = 0.f; i <= self.bgview.bounds.size.width; i++) { orignOffY = waveHeight * sinf(2 * M_PI / self.bgview.bounds.size.width * i + self.offset * M_PI * 2 / self.bgview.bounds.size.width) + self.height; CGPathAddLineToPoint(pathRef, NULL, i, orignOffY); } CGPathAddLineToPoint(pathRef, NULL, self.bgview.bounds.size.width, orignOffY); CGPathAddLineToPoint(pathRef, NULL, self.bgview.bounds.size.width, self.bgview.bounds.size.height); CGPathAddLineToPoint(pathRef, NULL, 0, self.bgview.bounds.size.height); CGPathAddLineToPoint(pathRef, NULL, 0, startOffY); CGPathCloseSubpath; self.firstLayer.path = pathRef; CGPathRelease; //第二条波纹路径 CGMutablePathRef pathRef1 = CGPathCreateMutable(); CGFloat startOffY1 = waveHeight * sinf(self.offset * M_PI * 2 / self.bgview.bounds.size.width); CGFloat orignOffY1 = 0.0; CGPathMoveToPoint(pathRef1, NULL, 0, startOffY1); for (CGFloat i = 0.f; i <= self.bgview.bounds.size.width; i++) { orignOffY1 = waveHeight * cosf(2 * M_PI / self.bgview.bounds.size.width * i + self.offset * M_PI * 2 / self.bgview.bounds.size.width) + self.height; CGPathAddLineToPoint(pathRef1, NULL, i, orignOffY1); } CGPathAddLineToPoint(pathRef1, NULL, self.bgview.bounds.size.width, orignOffY1); CGPathAddLineToPoint(pathRef1, NULL, self.bgview.bounds.size.width, self.bgview.bounds.size.height); CGPathAddLineToPoint(pathRef1, NULL, 0, self.bgview.bounds.size.height); CGPathAddLineToPoint(pathRef1, NULL, 0, startOffY1); CGPathCloseSubpath; self.secondLayer.path = pathRef1; CGPathRelease;}

当UITableView滑动时,改变self.payView的Y值,就足以兑现视图渐显的动作效果,此时亟需注意,须求动态更改self.headerView.layer.masksToBounds,至于原因嘛,我们能够惦记一下,实在想不知底就注释一下相应代码再看成效:

对于圆环内的label等控件,使用Masonry实行布局就可以,这里就只是多对Masonry实行认证,以上正是依附属中学国邮电通讯手提式有线电话机营业厅首页油滑进行的仿写,有哪些不足之处请大家建议。

-scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat contentOffsetY = scrollView.contentOffset.y; if (self.contentOffsetAction) { self.contentOffsetAction(contentOffsetY); } if (contentOffsetY <= 0) { // 当偏移量小于0时,头部视图的Y值跟随偏移量上移 self.payView.lyf_y = contentOffsetY; } else { // 头部视图滚动差的效果 self.payView.lyf_y = contentOffsetY/2; } self.payView.contentOffsetY = contentOffsetY; // 当contentOffsetY大于零时,打开裁剪功能。而小于零时,关闭裁剪 // 大家如果想知道不这样做的结果,就试着注释一下下面的代码试一试😜。 self.headerView.layer.masksToBounds = contentOffsetY > 0;}- scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:velocity targetContentOffset:(inout CGPoint *)targetContentOffset { CGFloat contentOffsetY = scrollView.contentOffset.y; if (contentOffsetY < -kHeaderHeight / 2) { // 当结束滑动的偏移量小于-kHeaderHeight / 2,就开始刷新tableView [self.mj_header beginRefreshing]; } else if (contentOffsetY > 0 && contentOffsetY < kHeaderHeight / 2) { // 当偏移量大于0并且小于kHeaderHeight / 2,就把偏移量设置在CGPointMake [self setContentOffset:CGPointMake animated:YES]; } else if (contentOffsetY > kHeaderHeight / 2 && contentOffsetY < kHeaderHeight) { // 当偏移量大于kHeaderHeight / 2并且小于kHeaderHeight,就把偏移量设置在CGPointMake(0, kHeaderHeight) [self setContentOffset:CGPointMake(0, kHeaderHeight) animated:YES]; }}

此时,除了刷新控件在UITableViewHeaderView上边呈现的效益未有兑现外,别的的都一点也不细略。那么最终便是完结那几个效果了,其实也很简短,当大家设置好刷新方法之后,动态的改变其距离最上部的冲天就可以了:

__weak __typeofweakSelf = self; // 下拉刷新 self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ [weakSelf loadMoreData]; }]; self.tableView.mj_header.ignoredScrollViewContentInsetTop = -kHeaderHeight;

世家分明留心,self.tableView.mj_header.ignoredScrollViewContentInsetTop方法必要在设定好底部刷新控件之后再调用。ok,代码小编会放在GitHub下面,喜欢的能够下载来看看,记得点个赞呦。GitHub:https://github.com/Fdevelopmenter/LYFTestAli2

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图