iOS 仿 UC 浏览器个人中心 (下拉实现果冻效果)

由于最近没什么项目,所以就试着模仿做了一些 App 的框架或者效果,今天做的是模仿 UC 浏览器个人中心的下拉效果,也有人称之为果冻效果或者是阻尼效果,本文用到了drawRect进行了底层的画线,不过还是很简单的只要把封装好的 MyHeaderView 放入工程中即可

效果图如下:





实现如下
ViewController.m:
[objc]  view plain  copy
  1. //  
  2. //  ViewController.m  
  3. //  PullAnimation  
  4. //  
  5. //  Created by Amydom on 16/10/29.  
  6. //  Copyright © 2016年 Amydom. All rights reserved.  
  7. //  
  8.   
  9. #import "ViewController.h"  
  10. #import "MyHeaderView.h"  
  11.   
  12.   
  13. @interface ViewController () <UITableViewDelegate, UITableViewDataSource>  
  14.   
  15. @property (strongnonatomicMyHeaderView *headerView;     // 上面蓝色的 view,可以自定义  
  16. @property (strongnonatomicUITableView *tableView;  
  17. @property (assign, nonatomic) CGFloat headerViewHeight;     // headerView 高度  
  18. @end  
  19.   
  20. @implementation ViewController  
  21.   
  22. - (void)viewDidLoad {  
  23.     [super viewDidLoad];  
  24.       
  25.     self.headerViewHeight = 180;  
  26.     [self createView];  
  27.       
  28.       
  29. }  
  30.   
  31. #pragma mark - initView  
  32. - (void)createView{  
  33.       
  34.     _tableView = [[UITableView alloc] init];  
  35.     _tableView.frame = self.view.bounds;  
  36.     _tableView.delegate = self;  
  37.     _tableView.dataSource = self;  
  38.     _tableView.rowHeight = 40;  
  39.     _tableView.sectionHeaderHeight = 20;  
  40.     _tableView.showsVerticalScrollIndicator = false;  
  41.     [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"mycell"];  
  42.     // 占位用的 view,高度 180  
  43.     UIView *view = [[UIView alloc] initWithFrame:CGRectMake(001self.headerViewHeight)];  
  44.     view.backgroundColor = [UIColor clearColor];  
  45.     _tableView.tableHeaderView = view;  
  46.     [self.view addSubview:self.tableView];  
  47.     // 蓝色的 headerView  
  48.     _headerView = [[MyHeaderView alloc] init];  
  49.     self.headerView.frame = CGRectMake(00self.view.frame.size.widthself.headerViewHeight);  
  50.     [self.view addSubview:self.headerView];  
  51. }  
  52.   
  53.   
  54.   
  55. #pragma mark - 监听 tableView.contentOffset,也可以用 kvo 监听  
  56.   
  57. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {  
  58.       
  59.     CGFloat offsetY = scrollView.contentOffset.y;  
  60.       
  61.     CGRect frame = self.headerView.frame;  
  62.     if (offsetY < 0) {  
  63.         frame.size.height = self.headerViewHeight - offsetY;  
  64.         frame.origin.y = 0;             // 及时归零  
  65.     } else {  
  66.         frame.size.height = self.headerViewHeight;  
  67.         frame.origin.y = -offsetY;  
  68.     }  
  69.     self.headerView.frame = frame;  
  70. }  
  71.   
  72.   
  73. // scrollViewWillEndDragging,这个方法内判断一下,contentOffset.y 值,如果超过多少值,那么自动回调一个 block,可实现下拉刷新  
  74. //松手时触发  
  75. - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{  
  76.       
  77.     CGFloat offsetY = scrollView.contentOffset.y;  
  78.     if (-offsetY > 70) {  
  79.           
  80.         NSLog(@"11111");  
  81.           
  82.     }  
  83.       
  84. }  
  85.   
  86. #pragma mark - tableView代理  
  87. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {  
  88.     return 30;  
  89. }  
  90.   
  91. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
  92.     static NSString *indetifier = @"mycell";  
  93.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:indetifier];  
  94.     cell.textLabel.text = @"Amydom";  
  95.     return cell;  
  96. }  
  97.   
  98. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {  
  99.     UITableViewHeaderFooterView *view = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"UITableViewHeaderFooterViewID"];  
  100.     if (view == nil) {  
  101.         view = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:@"UITableViewHeaderFooterViewID"];  
  102.         view.contentView.backgroundColor = [UIColor colorWithWhite:0.92 alpha:1.0];;  
  103.     }  
  104.     return view;  
  105. }  
  106.   
  107. @end  

MyHeaderView.m:
(这里是自定义的 UIView   MyHeaderView.h

@interface MyHeaderView : UIView

@end

)


[objc]  view plain  copy
  1. //  
  2. //  MyHeaderView.m  
  3. //  PullAnimation  
  4. //  
  5. //  Created by Amydom on 16/10/29.  
  6. //  Copyright © 2016年 Amydom. All rights reserved.  
  7. //  
  8.   
  9. #import "MyHeaderView.h"  
  10.   
  11.   
  12. @interface MyHeaderView ()  
  13.   
  14. @property (strongnonatomicUIImageView *imageV;          // 随便放一个 imageView  
  15. @property (assign, nonatomic) CGFloat headerViewHeight;     // headerView 高度  
  16. @property (assign, nonatomic) CGFloat screenWidth;  
  17.   
  18. @end  
  19.   
  20. @implementation MyHeaderView  
  21.   
  22. - (UIImageView *)imageV {  
  23.     if (_imageV == nil) {  
  24.         _imageV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ico_Default"]];  
  25.         _imageV.contentMode = UIViewContentModeScaleAspectFit;  
  26.         _imageV.userInteractionEnabled = true;  
  27.         [_imageV addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageViewTapAction:)]];  
  28.     }  
  29.     return _imageV;  
  30. }  
  31.   
  32. - (void)imageViewTapAction:(id)sender {  
  33.     NSLog(@"imageView tap");  
  34. }  
  35.   
  36. - (instancetype)init {  
  37.     if (self = [super init]) {  
  38.         self.backgroundColor = [UIColor clearColor];  
  39.         self.headerViewHeight = 180;  
  40.         self.screenWidth = [UIScreen mainScreen].bounds.size.width;  
  41.         [self addSubview:self.imageV];  
  42.     }  
  43.     return self;  
  44. }  
  45.   
  46. // 更改 frame 会触发 layoutSubviews  
  47. // 触发 layoutSubviews 后,这个 view 里面的控件想怎么变(旋转,位移,缩放),全部这个方法里面就好了  
  48. - (void)layoutSubviews {  
  49.     [super layoutSubviews];  
  50.       
  51.     // imageV 是 60 * 60 的  
  52.     CGFloat y = 60 + (self.frame.size.height - self.headerViewHeight) * 0.6;  
  53.     self.imageV.frame = CGRectMake((self.screenWidth - 60) * 0.5, y, 6060);  
  54.       
  55.     [self setNeedsDisplay];     // 重绘  
  56. }  
  57.   
  58. // 绘制曲线  
  59. - (void)drawRect:(CGRect)rect {  
  60.     //获取上下文  
  61.     //CGContextRef 用来保存图形信息.输出目标  
  62.     CGContextRef context = UIGraphicsGetCurrentContext();  
  63.     //设置颜色  
  64.     CGContextSetRGBFillColor(context, 0.003920.541170.850981.0);  
  65.       
  66.     CGFloat h1 = self.headerViewHeight;  
  67.     CGFloat w = rect.size.width;  
  68.     CGFloat h = rect.size.height;  
  69.     //起点  
  70.     CGContextMoveToPoint(context, w, h1);  
  71.     //画线  
  72.     CGContextAddLineToPoint(context, w, 0);  
  73.     CGContextAddLineToPoint(context, 00);  
  74.     CGContextAddLineToPoint(context, 0, h1);  
  75.     CGContextAddQuadCurveToPoint(context, w * 0.5, h + (h - h1) * 0.6, w, h1);  
  76.     //闭合  
  77.     CGContextClosePath(context);  
  78.       
  79.     CGContextDrawPath(context, kCGPathFill);  
  80. }  
  81.   
  82. // 这个 view 里面有多少个被点击的控件,把他的 frame 告诉 pointInside 就可以了  
  83. //这个函数会被 hitTest 调用,返回 false 表示点击的不是自己,返回 true 表示点击的是自己  
  84. - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {  
  85.     // 判断点击的点,在不在圆内  
  86.     CGPoint center = self.imageV.center;  
  87.     CGFloat r = self.imageV.frame.size.width * 0.5;  
  88.     CGFloat newR = sqrt((center.x - point.x) * (center.x - point.x) + (center.y - point.y) * (center.y - point.y));  
  89.       
  90.     // 浮点数比较不推荐用等号,虽然 ios 底层已经处理了这种情况  
  91.     if (newR > r) {  
  92.         return false;  
  93.     } else {  
  94.         return true;  
  95.     }  
  96. }  
  97. //- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;   hitTest 主要用来做事件分发的,可以实现不规则点击,它在整个 view 结构上是递归的  
  98.   
  99. @end  

因为做了判断,所以当点击 imageView(头像)时,无法响应下拉效果,这个可以根据需求进行修改!!


转载自:http://blog.csdn.net/amydom/article/details/53431362


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值