iOS-可拉伸放大的UITableView頭部視圖

前言git

App項目我的中心功能,通常是使用UITableView,可是若是不作處理,下拉的時候會顯示灰色的背景,很難看,爲了不這個問題,就是用一張圖片,根據tableview下拉的內容偏移量contentOffset,經過計算上下左右拉伸,遮蓋那個灰色的背景,達到美化的效果。由於這個功能很廣泛的使用,網絡上有不少的第三方,我在作項目的時候找到一個StretchHeader這個上下拉伸放大圖片的開源控件,應該符合咱們的功能需求;不過我在使用的過程當中發現了一些小Bug,修改並加上了一些邏輯判斷,以適應控制器是否設置automaticallyAdjustsScrollViewInsets屬性。github

 

(一)我認爲的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)。atom

#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,圖片會上下拉伸,左右放大;code

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

 

(四)總結圖片

這只是一個小小的功能,別人封裝的控件給了咱們不少的方便,但咱們也要有研究和鑽研代碼的精神,這是是學習之道。ip

相關文章
相關標籤/搜索