iOS自定義TableView收縮動畫

Xcode下載解決辦法:到該地址去手動下載安裝器安裝:
https://idmsa.apple.com/IDMSWebAuth/signin?appIdKey=891bd3417a7776362562d2197f89480a8547b108fd934911bcbea0110d07f757&path=%2Fdownload%2Fmore%2F&rv=1

//  SFMileageView.h

#import <UIKit/UIKit.h>

typedef void(^SFMileageViewBlock)(NSDictionary *);

@interface SFMileageView : UIView

@property (nonatomic, copy) NSString *title;

@property (nonatomic, copy) SFMileageViewBlock mileageViewBlock;

- (instancetype)initWithFrame:(CGRect)frame type:(NSInteger )type mileageViewBlock:(SFMileageViewBlock)block;

- (void)titleLabelChangeFontWithIndex:(CGFloat)index;

@end


//  SFMileageView.m

#import "SFMileageView.h"

@interface SFMileageView ()

@property (nonatomic, strong) UIImageView *imageView;

@property (nonatomic, strong) UILabel *titleLabel;

@property (nonatomic, assign) NSInteger type;
@end

@implementation SFMileageView

- (instancetype)initWithFrame:(CGRect)frame type:(NSInteger )type mileageViewBlock:(SFMileageViewBlock)block{
    self = [super initWithFrame:frame];
    if (self) {
        self.type = type;
        self.mileageViewBlock = block;

        self.titleLabel = [[UILabel alloc] init];
        self.titleLabel.font = [UIFont systemFontOfSize:16.0];
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
        self.titleLabel.adjustsFontSizeToFitWidth = YES;
        self.titleLabel.textColor = [UIColor whiteColor];
        [self addSubview:self.titleLabel];
        
        self.imageView = [[UIImageView alloc] init];
        self.imageView.contentMode = UIViewContentModeScaleAspectFit;
        self.imageView.image = [UIImage imageNamed:@"clear_voice"];
        [self addSubview:self.imageView];
        
        self.userInteractionEnabled  = YES;
        self.imageView.userInteractionEnabled = YES;
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(mileageViewTap:)];
        [self addGestureRecognizer:tap];
        
        if (type == 0) {
            self.imageView.hidden =  YES;
            self.titleLabel.frame = CGRectMake(0, 5, frame.size.width - 10, frame.size.height - 5);
            self.imageView.frame = CGRectMake(frame.size.width - 25, -5, 30, 30);
        }else{
            self.imageView.hidden =  NO;
            self.titleLabel.frame = CGRectMake(20, 5, frame.size.width - 20, frame.size.height - 5);
            self.imageView.frame = CGRectMake(-5, 0, 30, 30);
        }
        
    }
    return self;
}

- (void)mileageViewTap:(UITapGestureRecognizer *)sender
{
    if (self.mileageViewBlock) {
        self.mileageViewBlock(nil);
    }
}

- (void)setTitle:(NSString *)title
{
    if (self.type == 0) {
        if (!title || [title floatValue] <= 0) {
            title = @"0";
        }
        _title = title;
        NSString * text = [NSString stringWithFormat:@"  %@  %@",title, LOCAL(@"公里")];
        NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:text];
        NSRange range1 = [text rangeOfString:title];
        NSRange range2 = [text rangeOfString:LOCAL(@"公里")];
        [str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Arial" size:24] range:range1];
        [str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Arial" size:14] range:range2];
        self.titleLabel.attributedText = str;
    }else{
        self.titleLabel.text = title;
        self.imageView.centerY = self.titleLabel.centerY;
    }
   
}

- (void)titleLabelChangeFontWithIndex:(CGFloat)index
{
    CGFloat point = 0.4;
    if (index > point) {
        self.titleLabel.alpha = 0 + (index-point)/(1 - point);
    }else{
        self.titleLabel.alpha =  0 + (point - index)/point;
    }
    self.imageView.alpha = self.titleLabel.alpha - 0;

    if (self.type == 0) {
        NSString * text = @"";
        if (index > point) {
            self.imageView.hidden = NO;
            self.titleLabel.textAlignment = NSTextAlignmentRight;
            text = self.title;
        }else{
            self.imageView.hidden = YES;
            self.titleLabel.textAlignment = NSTextAlignmentCenter;
            text = [NSString stringWithFormat:@"   %@  %@",self.title, LOCAL(@"公里")];
        }
        self.titleLabel.frame = CGRectMake(0, 5, self.frame.size.width - 20 * index, self.frame.size.height - 5);

        CGFloat font = 5 * index;
        NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:text];
        NSRange range1 = [text rangeOfString:self.title];
        NSRange range2 = [text rangeOfString:LOCAL(@"公里")];
        [str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Arial" size:48 - 4 *font] range:range1];
        [str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Arial" size:16] range:range2];
        self.titleLabel.attributedText = str;
    }else{

        if (index > point) {
            self.imageView.hidden = YES;
            self.titleLabel.textAlignment = NSTextAlignmentLeft;
            self.titleLabel.text = LOCAL(@"當月里程(公里)");
            self.titleLabel.frame = CGRectMake(0, 5, self.frame.size.width, self.frame.size.height - 5);
            self.titleLabel.font = [UIFont fontWithName:@"Arial" size:18];
        }else{
            self.imageView.hidden = NO;
            self.titleLabel.textAlignment = NSTextAlignmentCenter;
            self.titleLabel.text = LOCAL(@"里程數僅作為參考,不作為最終計薪的里程");
            self.titleLabel.frame = CGRectMake(20, 5, self.frame.size.width - 20, self.frame.size.height -20 + 15.0/point * index);
            self.titleLabel.font = [UIFont fontWithName:@"Arial" size:16 + index * (2.0/point)];
        }
        self.imageView.centerY = self.titleLabel.centerY;
    }
    
}


@end



#import <UIKit/UIKit.h>

@interface SFMileageViewController : UIViewController

@end


@interface SFTableView : UITableView


//  SFMileageViewController.m


#import "SFMileageViewController.h"
#import "UIImage+SFGif.h"
#import "SFMileageView.h"

#define BottomWidth (250)

@interface SFMileageViewController ()<UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate>
@property (nonatomic, strong) SFTableView *tableView;
@property (nonatomic, strong) NSMutableArray *dataArr;

@property(nonatomic, strong)UIView *headView;

@property(nonatomic, strong)UIView *headTitleView;
@property(nonatomic, strong)UILabel *topTestLabel;
@property(nonatomic, strong)UILabel *bottomBtnLabel;

@property(nonatomic, strong)SFMileageView *centerTopView;
@property(nonatomic, strong)SFMileageView *centerBottomView;

@end

@implementation SFMileageViewController
#pragma mark - ViewCycle
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.title = LOCAL(@"我的里程");
    [self.view addSubview:self.headView];

    [self initTabView];
    
    if (self.dataArr.count == 0) {
        self.tableView.mj_footer.hidden = YES;
    }

}

#pragma mark--- CustomView
- (UIView *)headView{
    if (!_headView) {
        _headView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 120)];
        _headView.backgroundColor = UIMainColor;
        [_headView addSubview:self.headTitleView];
    }
    return _headView;
}

- (UIView *)headTitleView{
    if (!_headTitleView) {
        _headTitleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, _headView.frame.size.height-0)];
        _headTitleView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
        _headTitleView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0];
        
        _centerTopView = [[SFMileageView alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/2-60, 40, 120, 40) type:0 mileageViewBlock:^(NSDictionary * dict) {
            [SVProgressHUD showInfoWithStatus:@"展示里程說明彈窗"];
        }];
        [_headTitleView addSubview:_centerTopView];
        _centerTopView.title  = @"288";
        [_centerTopView titleLabelChangeFontWithIndex:0];
        
        _centerBottomView = [[SFMileageView alloc] initWithFrame:CGRectMake((SCREEN_WIDTH - BottomWidth)/2, 80, BottomWidth, 40) type:1 mileageViewBlock:nil];
        [_headTitleView addSubview:_centerBottomView];
        _centerBottomView.title  = LOCAL(@"里程數僅作為參考,不作為最終計薪的里程");
        [_centerBottomView titleLabelChangeFontWithIndex:0];
    }
    return _headTitleView;
}

#pragma mark----UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

    CGFloat offSetY = scrollView.contentOffset.y;
//    NSLog(@"===%f",offSetY);

    if (scrollView.tag==1000) {
        
        if (offSetY>=120) {
            scrollView.contentOffset = CGPointMake(0, offSetY);
            
            if (_headView.frame.size.height != 60) {
                NSInteger index = 1;
                [UIView animateWithDuration:0.05 animations:^{
                    CGFloat width = SCREEN_WIDTH/2-70;
                    _headView.frame = CGRectMake(0, 0, SCREEN_WIDTH, 120-60*(index));
                    _centerTopView.frame = CGRectMake(SCREEN_WIDTH/2-60+ width*index, 40-30*index, 120, 40);
                    [_centerTopView titleLabelChangeFontWithIndex:index];
                    CGFloat width1 = (SCREEN_WIDTH - BottomWidth)/2 - 10;
                    CGFloat width2 = (SCREEN_WIDTH - BottomWidth)/2;
                    _centerBottomView.frame = CGRectMake(width2 - width1*index, 80-70*index, BottomWidth, 40);
                    [_centerBottomView titleLabelChangeFontWithIndex:index];
                }];

            }
          
        }else if(offSetY>-0){

            CGFloat index = (offSetY+0)/120;
            [UIView animateWithDuration:0.05 animations:^{
                CGFloat width = SCREEN_WIDTH/2-70;
                _headView.frame = CGRectMake(0, 0, SCREEN_WIDTH, 120-60*(index));
                _centerTopView.frame = CGRectMake(SCREEN_WIDTH/2-60+ width*index, 40-30*index, 120, 40);
                [_centerTopView titleLabelChangeFontWithIndex:index];
                CGFloat width1 = (SCREEN_WIDTH - BottomWidth)/2 - 10;
                CGFloat width2 = (SCREEN_WIDTH - BottomWidth)/2;
                _centerBottomView.frame = CGRectMake(width2 - width1*index, 80-70*index, BottomWidth, 40);
                [_centerBottomView titleLabelChangeFontWithIndex:index];
            }];
        }else {
            if (_headView.frame.size.height != 120) {
                NSInteger index = 0;
                [UIView animateWithDuration:0.05 animations:^{
                    CGFloat width = SCREEN_WIDTH/2-70;
                    _headView.frame = CGRectMake(0, 0, SCREEN_WIDTH, 120-60*(index));
                    _centerTopView.frame = CGRectMake(SCREEN_WIDTH/2-60+ width*index, 40-30*index, 120, 40);
                    [_centerTopView titleLabelChangeFontWithIndex:index];
                    CGFloat width1 = (SCREEN_WIDTH - BottomWidth)/2 - 10;
                    CGFloat width2 = (SCREEN_WIDTH - BottomWidth)/2;
                    _centerBottomView.frame = CGRectMake(width2 - width1*index, 80-70*index, BottomWidth, 40);
                    [_centerBottomView titleLabelChangeFontWithIndex:index];
                }];

            }
        }
        
    }
}



- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    CGFloat offSetY = scrollView.contentOffset.y;
    NSLog(@"111111111111:%.2f",scrollView.contentOffset.y);

    [UIView animateWithDuration:0.05 animations:^{
        if (offSetY > 50 && offSetY <= 120) {
            [scrollView setContentOffset:CGPointMake(0, 120) animated:YES];
        }
        
        if (offSetY > 0 && offSetY <= 50) {
            [scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
        }
    }];
   
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
//    CGFloat offSetY = scrollView.contentOffset.y;
//    if (offSetY > 30 && offSetY <= 120) {
//        [scrollView setContentOffset:CGPointMake(0, 120) animated:YES];
//    }
////    NSLog(@"offSetY---%.2f",offSetY);
//    if (offSetY > -1120 && offSetY <= 30) {
//        [scrollView setContentOffset:CGPointMake(0, -0) animated:YES];
//    }
    NSLog(@"2222222222222:%.2f",scrollView.contentOffset.y);

}


- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset NS_AVAILABLE_IOS(5_0);
{
    NSLog(@"333333333333333:%.2f",scrollView.contentOffset.y);
//    CGFloat offSetY = scrollView.contentOffset.y;
//    if (offSetY > 30 && offSetY <= 120) {
//        [scrollView setContentOffset:CGPointMake(0, 120) animated:YES];
//    }
//    if (offSetY > -1120 && offSetY <= 30) {
//        [scrollView setContentOffset:CGPointMake(0, -0) animated:YES];
//    }

}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
{
    CGFloat offSetY = scrollView.contentOffset.y;

    NSLog(@"44444444444444:%.2f",scrollView.contentOffset.y);
    [UIView animateWithDuration:0.05 animations:^{
        if (offSetY > 50 && offSetY <= 120) {
            [scrollView setContentOffset:CGPointMake(0, 120) animated:YES];
        }
        if (offSetY > 0 && offSetY <= 50) {
            [scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
        }
    }];
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView

{
//    NSLog(@"555555555555555---%.2f",scrollView.contentOffset.y);

}


-(void)initTabView
{
    self.view.userInteractionEnabled = YES;
    self.view.backgroundColor = kGrayColor(241);
    [self.view addSubview:self.tableView];
    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.headView.mas_bottom).offset(0);
        make.left.equalTo(self.view).offset(0);
        make.right.equalTo(self.view).offset(0);
        make.bottom.equalTo(self.view).offset(0);
    }];
    
    // 設置header
    MJRefreshGifHeader *header = [MJRefreshGifHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];
    UIImage *gifImage = [UIImage sf_animatedGIFNamed:@"pull_down_loading"];
    [header setImages:@[gifImage] forState:MJRefreshStateRefreshing];
    [header setImages:@[[UIImage imageNamed:@"line_bg_image"]] forState:MJRefreshStateIdle];
    self.tableView.mj_header = header;

    // 設置footer
    MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
    [footer setTitle:LOCAL(@"pullup_loading") forState:MJRefreshStateIdle];
    [footer setTitle:LOCAL(@"loading_more_data") forState:MJRefreshStateRefreshing];
    [footer setTitle:LOCAL(@"no_more") forState:MJRefreshStateNoMoreData];
    self.tableView.mj_footer = footer;
}

- (void)loadNewData
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.tableView.mj_header endRefreshing];
        [self.tableView.mj_footer endRefreshing];
    });
   
}

- (void)loadMoreData
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.tableView.mj_header endRefreshing];
        [self.tableView.mj_footer endRefreshing];
    });
}


- (UITableView *)tableView
{
    if (!_tableView) {
        _tableView = [[SFTableView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) style:UITableViewStylePlain];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        [_tableView setBackgroundColor:UIMainBackColor];
        _tableView.tableFooterView = [[UIView alloc] init];
        [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
        _tableView.estimatedRowHeight = 0;
        _tableView.estimatedSectionHeaderHeight = 0;
        _tableView.estimatedSectionFooterHeight = 0;
        _tableView.tag = 1000;

    }
    return _tableView;
}


#pragma mark - UITableViewDelegate & UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.dataArr.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 80;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    cell.textLabel.text = [NSString stringWithFormat:@"cell--%@--",self.dataArr[indexPath.row]];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
   
}


- (NSMutableArray *)dataArr
{
    if (!_dataArr) {
        _dataArr = [[NSMutableArray alloc] init];
        for (NSInteger i = 0; i < 10; i ++) {
            [_dataArr addObject:@(i)];
        }
    }
    return _dataArr;
}


@end


@interface SFTableView()<UIGestureRecognizerDelegate>


@end
@implementation SFTableView
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}
@end
@implementation UCButton
- (instancetype )initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
        self.titleLabel.font = [UIFont systemFontOfSize:15];
        [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    }
    return self;
}

- (void)layoutSubviews{
    [super layoutSubviews];
    CGFloat btnHeight = self.frame.size.height-10;
    self.imageView.center = CGPointMake(self.frame.size.width/2, btnHeight*2/3/2+5);
    self.imageView.bounds = CGRectMake(0, 0, btnHeight*2/3-5, btnHeight*2/3-5);
    self.titleLabel.frame = CGRectMake(0, btnHeight*2/3+5, self.frame.size.width, btnHeight/3);
}
@end

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,460評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,067評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,467評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,468評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,184評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,582評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,794評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,343評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,096評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,291評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,513評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,941評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,190評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,026評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,253評論 2 375

推薦閱讀更多精彩內容