iOS-可拉伸放大的UITableView头部视图

前言

App项目个人中心功能,一般是使用UITableView,但是如果不做处理,下拉的时候会显示灰色的背景,很难看,为了避免这个问题,就是用一张图片,根据tableview下拉的内容偏移量contentOffset,通过计算上下左右拉伸,遮盖那个灰色的背景,达到美化的效果。因为这个功能很普遍的使用,网络上有很多的第三方,我在做项目的时候找到一个StretchHeader这个上下拉伸放大图片的开源控件,应该符合我们的功能需求;不过我在使用的过程中发现了一些小Bug,修改并加上了一些逻辑判断,以适应控制器是否设置automaticallyAdjustsScrollViewInsets属性。

 

(一)我认为的StretchHeader这个第三方的部分小bug;在下拉tableview的过程中,上拉tableview右侧会出现白边(view左移造成的)。

- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
    /*出现bug的代码
    CGRect f     = _view.frame;
    f.size.width = _tableView.frame.size.width;
    _view.frame  = f;
    */
    
    if(scrollView.contentOffset.y < 0)
    {
        CGFloat offsetY = (scrollView.contentOffset.y + scrollView.contentInset.top) * -1;
       
        initialFrame.origin.y = - offsetY * 1;
        initialFrame.origin.x = - offsetY / 2;
        
        initialFrame.size.width  = _tableView.frame.size.width + offsetY;
        initialFrame.size.height = defaultViewHeight + offsetY;
        
        _view.frame = initialFrame;
    }
}

上述源码是第三方StretchHeader的一段代码,我注释的部分就是出现bug的代码,我们可以看一下,这个方法是计算view上下左右拉伸幅度的(即重新设置frame的地方),注释的3句代码,在每次滑动tableview的过程中都会把view的width设置成tableview的width,相当于没有被拉伸过的宽度,但是origin.x却是被拉伸计算的,不是原来的值,这就会使得在下拉的过程中在右侧会出现白边,(因为view在拉伸过程中已经被左移),下部分说一下我的解决办法。

 

(二)我的解决思路,在判断的条件范围内(scrollView.contentOffset.y <= initialOffsetY)设置view的frame都在tableview滑动的时候计算并赋值,并加上临界点的判断(在临界点也计算view的frame),防止tableview停止滑动时view的frame计算错误;CGFloat initialOffsetY = automaticallyAdjustsScrollViewInsets ? -64 : 0;这一句就是获取tableview判断临界的值,-64或者是0(如果controller设置了automaticallyAdjustsScrollViewInsets属性为NO,值为0;反之为-64)。

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface StretchableTableHeader : NSObject

@property (nonatomic,strong) UITableView *tableView;
@property (nonatomic,strong) UIView *view;

- (void)stectchHeaderForTableView:(UITableView *)tableView withView:(UIView *)view subViews:(UIView *)subView;
- (void)scrollViewDidScroll:(UIScrollView*)scrollView isAutomaticallyAdjustsScrollViewInsets:(BOOL)automaticallyAdjustsScrollViewInsets;//判断view是否设置automaticallyAdjustsScrollViewInsets属性,来设置scrollView.contentOffset.y的判断基准点,即-64或0;

- (void)resizeView;

@end


#import "StretchableTableHeader.h"

@interface StretchableTableHeader ()
{
    CGRect initFrame;//view初始的frame,会改变;
    CGFloat defaultViewHeight;//view初始的高度;
}

@end

@implementation StretchableTableHeader

- (void)stectchHeaderForTableView:(UITableView *)tableView withView:(UIView *)view subViews:(UIView *)subView
{
    _tableView = tableView;
    _view = view;
    
    initFrame = _view.frame;
    defaultViewHeight = initFrame.size.height;
    
    UIView *emptyTableHeaderView = [[UIView alloc] initWithFrame:initFrame];
    _tableView.tableHeaderView = emptyTableHeaderView;
    
    
    [_tableView addSubview:_view];
    [_tableView addSubview:subView];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView isAutomaticallyAdjustsScrollViewInsets:(BOOL)automaticallyAdjustsScrollViewInsets
{
    CGFloat initialOffsetY = automaticallyAdjustsScrollViewInsets ? -64 : 0;
    if (scrollView.contentOffset.y <= initialOffsetY)
    {
        //下拉的偏移量;
        CGFloat offsetY = (scrollView.contentOffset.y + scrollView.contentInset.top) * -1;
        initFrame.origin.y = -offsetY * 1;//设置上下拉伸的幅度;
        initFrame.origin.x = -offsetY / 2;//设置左右拉伸的幅度;
        
        //重新设置view的frame(高度和宽度加上offsetY偏移量,达到图片放大的效果);
        initFrame.size.width = _tableView.frame.size.width + offsetY;
        initFrame.size.height = defaultViewHeight + offsetY;
        _view.frame = initFrame;
    }
}

- (void)resizeView
{
    initFrame.size.width = _tableView.frame.size.width;
    _view.frame = initFrame;
}
@end

 

(三)使用的代码实例;下拉tableview,图片会上下拉伸,左右放大;

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    self.navigationItem.title = @"个人中心";
    [self.view addSubview:self.tbl];
    
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    imageView.clipsToBounds = YES;
    imageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"photo" ofType:@".jpg"]];
    
    
    UIView *contentView = [[UIView alloc] initWithFrame:imageView.bounds];
    UIImageView *avater = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 90, 90)];
    avater.image = [UIImage imageNamed:@"avater"];
    avater.center = contentView.center;
    [contentView addSubview:avater];
    
    
    self.stretchableTableHeader = [StretchableTableHeader new];
    [self.stretchableTableHeader stectchHeaderForTableView:self.tbl withView:imageView subViews:contentView];
    
    
    UIBarButtonItem *right = [[UIBarButtonItem alloc] initWithTitle:@"+" style:UIBarButtonItemStyleDone target:self action:@selector(add)];
    self.navigationItem.rightBarButtonItem = right;
    
    self.dataSourceArray = [NSMutableArray arrayWithContentsOfFile:[self filePath]];
    [self.tbl reloadData];
    
    self.navigationController.toolbarHidden = NO;
    
    self.navigationController.toolbar.backgroundColor = [UIColor whiteColor];
}


- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [self.stretchableTableHeader scrollViewDidScroll:scrollView isAutomaticallyAdjustsScrollViewInsets:self.automaticallyAdjustsScrollViewInsets];
}
- (void)viewDidLayoutSubviews
{
    [self.stretchableTableHeader resizeView];
}

 

(四)总结

这只是一个小小的功能,别人封装的控件给了我们很多的方便,但我们也要有研究和钻研代码的精神,这是是学习之道。

 

 

转载于:https://my.oschina.net/u/1450995/blog/685950

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值