iOS开发之制作自定义效果的头视图(一)

108 篇文章 1 订阅

  在iOS开发的过程中,我们会遇到产品给我们提出的要求,让我们做一些特殊的头视图效果。有时甚至是几种头视图效果的组合,本人也是深受其害。唉,为了摆脱困境,觉得很有必要打造一款合适的工具。以备不时之需。而关于自定义头视图,在实际的开发过程中,主要是UITableView,UICollectionViewUIScrollView这三种视图用到的较多,而UITableViewUICollectionView都是UIScrollView的子视图,所以我这边就是UIScrollView为基础制作一个工具。
&emsp: 接下来大家看一下下面的这个枚举,目前我这边实现了如下的几种效果

typedef NS_ENUM(NSInteger,JKScrollStyle) {
 JKScrollStyleHeaderNormal = 0,      ///< 头视图不放大
 JKScrollStyleHeaderScale,           ///< 头视图随着向下划动放大
 JKScrollStyleHeaderScaleWithSystem, ///< 头视图随着向下划动放大,并且和系统头视图形成层叠关系
 JKScrollStyleHeaderNormalWithSection ///< 头视图不放大,并且和sectionHeader形成层叠关系
};

下面依次是相关效果的gif动画 JKScrollStyleHeaderNormal = 0, ///< 头视图不放大

这里写图片描述

JKScrollStyleHeaderScale,           ///< 头视图随着向下划动放大

这里写图片描述

JKScrollStyleHeaderScaleWithSystem, ///< 头视图随着向下划动放大,并且和系统头视图形形成层叠关系

这个是透明浮层不进行缩放,
这里写图片描述

JKScrollStyleHeaderNormalWithSection ///< 头视图不放大,并且和sectionHeader形成层叠关系

这种事section突出来一部分的效果实现
这里写图片描述
看完了效果,大家来看看实现代码吧。

#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger,JKScrollStyle) {
 JKScrollStyleHeaderNormal = 0,      ///< 头视图不放大
 JKScrollStyleHeaderScale,           ///< 头视图随着向下划动放大
 JKScrollStyleHeaderScaleWithSystem, ///< 头视图随着向下划动放大,并且和系统头视图形成层叠关系
 JKScrollStyleHeaderNormalWithSection ///< 头视图不放大,并且和sectionHeader形成层叠关系
};
@interface JKScrollViewHelper : NSObject

/**
 初始化方法

 @param scrollView 滚动视图
 @param headerView 头视图
 @param style 风格
 @return helper对象
 */
- (id)initWithScrollView:(UIScrollView *)scrollView headerView:(UIView *)headerView style:(JKScrollStyle)style;
/**
 滚动时透视图执行相关的放大操作,放在scrollViewDidScroll:这个方法中

 @param scrollView 滚动视图
 @param insetHeight scrollView距离父视图顶部的缩进
 */
- (void)scrollViewDidSroll:(UIScrollView *)scrollView superViewInsetHeight:(CGFloat)insetHeight;
#import "JKScrollViewHelper.h"
@interface JKScrollViewHelper()
@property (nonatomic,assign)CGSize defautHeaderSize;
@property (nonatomic,weak) UIView *headerView;
@property (nonatomic,assign) JKScrollStyle scrollStyle;
@property (nonatomic,assign) CGFloat contentInsetTop;
@property (nonatomic,assign) CGFloat originHeaderY;
@end
@implementation JKScrollViewHelper
- (id)initWithScrollView:(UIScrollView *)scrollView headerView:(UIView *)headerView style:(JKScrollStyle)style{
    self = [super init];
    if(self){

        CGRect frame = headerView.frame;
        headerView.clipsToBounds = YES;
        self.headerView = headerView;
        self.scrollStyle = style;
        CGFloat height = 0;

        if ([scrollView isKindOfClass:[UITableView class]]) {
            UITableView *tableView = (UITableView *)scrollView;
            if (style == JKScrollStyleHeaderScaleWithSystem) {
                UIView *tableHeaderView = (UITableView *)tableView.tableHeaderView;
                height = tableHeaderView.frame.size.height;
            }else if (style == JKScrollStyleHeaderNormalWithSection){
                CGRect sectionRect = [tableView rectForHeaderInSection:0];
                height = sectionRect.size.height;
            }


        }
        self.defautHeaderSize = frame.size;
        self.contentInsetTop = frame.size.height-height;
            scrollView.contentInset = UIEdgeInsetsMake(self.contentInsetTop, 0, 0, 0);
            [scrollView setContentOffset:CGPointMake(0, -self.contentInsetTop) animated:NO];
            scrollView.bouncesZoom = NO;
        self.originHeaderY = HUGE_VAL;
    }
    return self;
}

- (void)scrollViewDidSroll:(UIScrollView *)scrollView superViewInsetHeight:(CGFloat)insetHeight{

    CGPoint point = scrollView.contentOffset;
    CGFloat originOffsetY = point.y+insetHeight;
//    NSLog(@"originOffsetY %@",@(originOffsetY));
   CGRect rect = self.headerView.frame;
    if (self.originHeaderY == HUGE_VAL) {
        self.originHeaderY = rect.origin.y;
    }
    switch (self.scrollStyle) {
        case JKScrollStyleHeaderNormal:
        {
            if (originOffsetY<= -self.defautHeaderSize.height) {
            rect.origin.y = fabs(originOffsetY)-self.defautHeaderSize.height;
            }else{
            rect.origin.y = -(originOffsetY+self.defautHeaderSize.height);
            }
            rect.size.height = self.defautHeaderSize.height;
            self.headerView.frame = rect;
        }
            break;
        case JKScrollStyleHeaderScale:
        {
           if (originOffsetY<= -self.defautHeaderSize.height) {
               rect.origin.y = self.originHeaderY;
                rect.size.height = - originOffsetY;
           }else if (originOffsetY> -self.defautHeaderSize.height){
               rect.origin.y = -(originOffsetY+self.defautHeaderSize.height);
               rect.size.height = self.defautHeaderSize.height;
           }
            self.headerView.frame = rect;
        }
            break;
        case JKScrollStyleHeaderScaleWithSystem:
        {
            if (originOffsetY<= -self.contentInsetTop) {
                rect.origin.y = self.originHeaderY;
                rect.size.height = fabs(originOffsetY)-self.contentInsetTop + self.defautHeaderSize.height;
                self.headerView.frame = rect;
            }else if (originOffsetY> -self.contentInsetTop){
                rect.origin.y = -originOffsetY-self.contentInsetTop;
                rect.size.height = self.defautHeaderSize.height;
                self.headerView.frame = rect;

            }
        }
            break;
        case JKScrollStyleHeaderNormalWithSection:
        {
            if (originOffsetY<= -self.contentInsetTop) {
                rect.origin.y = fabs(originOffsetY)-self.contentInsetTop;
            }else{
                rect.origin.y = -originOffsetY-self.contentInsetTop;
            }
            rect.size.height = self.defautHeaderSize.height;
            self.headerView.frame = rect;
        }
            break;

        default:
            break;
    }
}

代码下载地址:https://github.com/xindizhiyin2014/JKUIHelper
方法实现非常的简单,主要就是通过设置headerView的frame,以及scrolllview的contentInset来实现的。但是通过集成后,通用性会加强一些。提高大家的开发效率。
这几种效果是根据自己经常用到的效果来实现的,当然了还有很多的效果没有实现。大家如果有哪些好的效果可以多多交流。QQ扫描二维码可以进群交流
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值