一行代碼實(shí)現(xiàn)headView彈簧拉伸效果

blog_demo.gif

前言

很多app的個(gè)人中心上部的headView都實(shí)現(xiàn)了彈簧拉伸的效果,即tableView的top并不隨著下拉而滑動(dòng),而是緊緊的停在屏幕的最上方。
我們今天就分析一下這個(gè)效果的實(shí)現(xiàn)方式。


分析

blog1_spec.png

關(guān)鍵代碼

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.tableView];
    
    self.headView.bounds = CGRectMake(0, 0, self.tableView.bounds.size.width, 200);
    self.tableView.tableHeaderView = self.headView;
    self.topImageView.frame = self.headView.bounds;
    [self.headView addSubview:self.topImageView];
    
    //在viewDidLoad方法中記錄原始的y和height
    self.originY = self.topImageView.y;
    self.originHeight = self.topImageView.height;
}


#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGFloat offy = scrollView.contentOffset.y;
    if (offy < 0) {
        self.topImageView.y = offy;
        self.topImageView.height = self.originHeight - offy;
    }else{
        self.topImageView.y = self.originY;
        self.topImageView.height = self.originHeight;
    }
}

ok,到此你已經(jīng)實(shí)現(xiàn)了headView的彈簧效果了!

多想一步,進(jìn)一步優(yōu)化

雖然上面已經(jīng)實(shí)現(xiàn)了功能所需,但是這個(gè)效果的代碼跟項(xiàng)目耦合在一起的,不能復(fù)用。每次實(shí)現(xiàn)這個(gè)效果,都要寫一遍上面的代碼。不能忍啊,我們進(jìn)一步優(yōu)化!

我們創(chuàng)建一個(gè)名為UIScrollView+SpringHeadView.h的UIScrollView的分類

UIScrollView+SpringHeadView類中的實(shí)現(xiàn)方法如下

//UIScrollView+SpringHeadView.h的內(nèi)容
#import <UIKit/UIKit.h>
//headView 的高度
#define SpringHeadViewHeight 200

@interface UIScrollView (SpringHeadView)<UIScrollViewDelegate>
//在分類增加了屬性,這個(gè)是利用runtime實(shí)現(xiàn)的
@property (nonatomic, weak) UIView *topView;
- (void)addSpringHeadView:(UIView *)view;
@end
//UIScrollView+SpringHeadView.m的內(nèi)容
- (void)setTopView:(UIView *)topView{
    [self willChangeValueForKey:@"SpringHeadView"];
    objc_setAssociatedObject(self, &UIScrollViewSpringHeadView,
                             topView,
                             OBJC_ASSOCIATION_ASSIGN);
    [self didChangeValueForKey:@"SpringHeadView"];
}

- (UIView *)topView{
    return objc_getAssociatedObject(self, &UIScrollViewSpringHeadView);
}


- (void)addSpringHeadView:(UIView *)view{
    self.contentInset = UIEdgeInsetsMake(view.bounds.size.height, 0, 0, 0);
    [self addSubview:view];
    view.frame = CGRectMake(0, -view.bounds.size.height, view.bounds.size.width, view.bounds.size.height);
    self.topView = view;
    //使用kvo監(jiān)聽scrollView的滾動(dòng)
    [self addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    [self scrollViewDidScroll:self];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGFloat offy = scrollView.contentOffset.y;
    
    if (offy < 0) {
        self.topView.frame = CGRectMake(0, offy, self.topView.bounds.size.width, -offy);
    }
}

現(xiàn)在我們使用起來爽了,只要需要引入UIScrollView+SpringHeadView.h,一行代碼就能實(shí)現(xiàn)彈簧的效果啦!

//引入分類
#import "UIScrollView+SpringHeadView.h"

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.tableView];
    
    self.topImageView.frame = CGRectMake(0, 0, self.tableView.bounds.size.width, SpringHeadViewHeight);
    //只需要一行代碼,就能實(shí)現(xiàn)同樣效果
    [self.tableView addSpringHeadView:self.topImageView];
}

獲取完整的代碼點(diǎn)我

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容