自制一个UIView代替ViewController的导航栏视图跟随scrollview滑动而改变大小并且图片移动交错效果,列表的Header View中的图片产生视差滚动效果
Posted Jk_Chan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自制一个UIView代替ViewController的导航栏视图跟随scrollview滑动而改变大小并且图片移动交错效果,列表的Header View中的图片产生视差滚动效果相关的知识,希望对你有一定的参考价值。
#import <UIKit/UIKit.h>
@interface ELHeaderView : UIView
@property (nonatomic, weak) UIViewController *viewController;
@property (nonatomic, weak) UIScrollView *scrollView;
- (id)initWithFrame:(CGRect)frame backGroudImageURL:(NSString *)backImageURL headerImageURL:(NSString *)headerImageURL title:(NSString *)title subTitle:(NSString *)subTitle;
-(void)updateSubViewsWithScrollOffset:(CGPoint)newOffset;
@end
#import "ELHeaderView.h"
#import "UIImageView+WebCache.h"
#pragma mark - notes:
/*
self:
UIView
self.clipsToBounds = YES;//这个很重要
重写-(void)willMoveToSuperview:(UIView *)newSuperview方法设置一些视图对象(这方法执行时已经被加载对象出来了):
1.隐藏自己被添加到的viewControler成员对象的导航栏:
[[self.viewController navigationController] setNavigationBarHidden:YES];
2.让自己成为自己的scrollView成员变量的观察者(KVO)观察它的contentOffset:
[self.scrollView addObserver:self forKeyPath:@"contentOffset" options:(NSKeyValueObservingOptionNew) context:Nil];
因此需要实现KVO观察者回调拿到新的scrollerView的contentOffset:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
并且在该回调中调用自定义方法计算改变各个view的位置以及渐隐以及字体大小:
-(void)updateSubViewsWithScrollOffset:(CGPoint)newOffset;
3.设置scrollView的顶部的间隔区域://这个很重要
self.scrollView.contentInset = UIEdgeInsetsMake(self.frame.size.height, 0 ,0, 0);
scrollerView:
被添加到的viewController:
背景图:
附在self上
Y为-self.frame.size.height/2
高是self.frame.size.height*1.5
表头图片:
附在self上
z轴在背景图上
调整大小,位置
表头主标题:
附在self上
z轴在背景图上
调整大小,位置
表头副标题:
附在self上
z轴在背景图上
调整大小,位置
*/
@interface ELHeaderView()
@property (nonatomic, strong) UIImageView *backImageView;
@property (nonatomic, strong) UIImageView *headerImageView;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic,strong) UILabel *subTitleLabel;
@end
@implementation ELHeaderView
- (id)initWithFrame:(CGRect)frame backGroudImageURL:(NSString *)backImageURL headerImageURL:(NSString *)headerImageURL title:(NSString *)title subTitle:(NSString *)subTitle{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor whiteColor];
_backImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, -0.5*frame.size.height, frame.size.width, frame.size.height*1.5)];
[_backImageView setImageWithURL:[NSURL URLWithString:backImageURL]];
_headerImageView = [[UIImageView alloc] initWithFrame:CGRectMake(frame.size.width*0.5-0.125*frame.size.height, 0.25*frame.size.height, 0.25*frame.size.height, 0.25*frame.size.height)];
[_headerImageView setImageWithURL:[NSURL URLWithString:headerImageURL]];
_titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0.6*frame.size.height, frame.size.width, frame.size.height*0.2)];
_titleLabel.textAlignment = NSTextAlignmentCenter;
_titleLabel.font = [UIFont boldSystemFontOfSize:20];
_titleLabel.text = title;
_subTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0.85*frame.size.height, frame.size.width, frame.size.height*0.1)];
_subTitleLabel.textAlignment = NSTextAlignmentCenter;
_subTitleLabel.font = [UIFont systemFontOfSize:12];
_subTitleLabel.text = subTitle;
_titleLabel.textColor = [UIColor whiteColor];
_subTitleLabel.textColor = [UIColor whiteColor];
[self addSubview:_backImageView];
[self addSubview:_headerImageView];
[self addSubview:_titleLabel];
[self addSubview:_subTitleLabel];
self.clipsToBounds = YES;
}
return self;
}
-(void)willMoveToSuperview:(UIView *)newSuperview{
[[self.viewController navigationController] setNavigationBarHidden:YES];
[self.scrollView addObserver:self forKeyPath:@"contentOffset" options:(NSKeyValueObservingOptionNew) context:Nil];
self.scrollView.contentInset = UIEdgeInsetsMake(self.frame.size.height, 0 ,0, 0);
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
CGPoint newOffset = [change[@"new"] CGPointValue];
[self updateSubViewsWithScrollOffset:newOffset];
}
-(void)updateSubViewsWithScrollOffset:(CGPoint)newOffset{
float destinaOffset = -60;
float startChangeOffset = -self.scrollView.contentInset.top;
newOffset = CGPointMake(newOffset.x, newOffset.y<startChangeOffset?startChangeOffset:(newOffset.y>destinaOffset?destinaOffset:newOffset.y));
float titleDestinateOffset = self.frame.size.height-40;
float newY = -newOffset.y-self.scrollView.contentInset.top;
float d = destinaOffset-startChangeOffset;
float alpha = 1-(newOffset.y-startChangeOffset)/d;
self.subTitleLabel.alpha = alpha;
self.frame = CGRectMake(0, newY, self.frame.size.width, self.frame.size.height);
self.backImageView.frame = CGRectMake(0, -0.5*self.frame.size.height+(1.5*self.frame.size.height-60)*(1-alpha), self.backImageView.frame.size.width, self.backImageView.frame.size.height);
self.titleLabel.frame = CGRectMake(0, 0.6*self.frame.size.height+(titleDestinateOffset-0.6*self.frame.size.height)*(1-alpha), self.titleLabel.frame.size.width, self.titleLabel.frame.size.height);
self.titleLabel.font = [UIFont boldSystemFontOfSize:16+(alpha)*4];
}
@end
以上是关于自制一个UIView代替ViewController的导航栏视图跟随scrollview滑动而改变大小并且图片移动交错效果,列表的Header View中的图片产生视差滚动效果的主要内容,如果未能解决你的问题,请参考以下文章