在iOS开发的过程中,我们会遇到产品给我们提出的要求,让我们做一些特殊的头视图效果。有时甚至是几种头视图效果的组合,本人也是深受其害。唉,为了摆脱困境,觉得很有必要打造一款合适的工具。以备不时之需。而关于自定义头视图,在实际的开发过程中,主要是UITableView
,UICollectionView
,UIScrollView
这三种视图用到的较多,而UITableView
,UICollectionView
都是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扫描二维码可以进群交流