iOS开发中视图的下拉放大和上拉模糊的效果实现
iOS开发中视图的下拉放大和上拉模糊的效果实现
发布时间:2016-12-28 来源:查字典编辑
摘要:把"秘密"的Cell效果整体视图都放到scrollView中,基本是和secretapp一模一样的效果了.代码如下:(模糊效果的类就不写了,...

把"秘密"的Cell效果整体视图都放到scrollView中,基本是和secret app 一模一样的效果了.

代码如下:(模糊效果的类就不写了,大家可以搜"UIImage+ImageEffects",还要导入Accelerate.framework)

1.MTSecretAppEffect.h

复制代码 代码如下:

#import <Foundation/Foundation.h>

@interface MTSecretAppEffect : NSObject

/**

* 创建整体的scrollView,把headScrollView和tableView全部加载在上面,靠它来上下滑动,其余的滑动全部禁止

*

* @return mainScrollView

*/

- (UIScrollView *)createMainScrollView;

/**

* 创建headScrollView

*

* @return headScrollView

*/

- (UIScrollView *)createHeadScrollView;

/**

* 创建头部的模糊view

*

* @param scrollview headScrollView

*

* @return blurImageView

*/

- (UIImageView *)createBlurImageViewOfView:(UIScrollView *)scrollview;

/**

* 在- (void)scrollViewDidScroll:(UIScrollView *)scrollView 中调用的方法

*

* @param scrollView

* @param mainScrollView

* @param tableView

* @param headScrollView

* @param blurImageView

*/

- (void)scrollDidScrollView:(UIScrollView *)scrollView withMainScrollView:(UIScrollView *)mainScrollView withTableView:(UITableView *)tableView withHeadScrollView:(UIScrollView *)headScrollView withBlurImageView:(UIImageView *)blurImageView;

@end

2.MTSecretAppEffect.m

复制代码 代码如下:

#import "MTSecretAppEffect.h"

#import "UIImage+ImageEffects.h"

#import <QuartzCore/QuartzCore.h>

#define HEADER_HEIGHT 200.0f

#define HEADER_INIT_FRAME CGRectMake(0, 0, 320, HEADER_HEIGHT)

const CGFloat kBarHeight = 50.0f;

const CGFloat kBackgroundParallexFactor = 0.5f;

const CGFloat kBlurFadeInFactor = 0.015f;

@implementation MTSecretAppEffect

// 欠缺:调用者设置代理

- (UIScrollView *)createMainScrollView{

// 和Self.view同大小的底部ScrollView

UIScrollView *mainScrollView = [[UIScrollView alloc] initWithFrame:[UIApplication sharedApplication].keyWindow.frame];

mainScrollView.bounces = YES;

mainScrollView.alwaysBounceVertical = YES;

mainScrollView.contentSize = CGSizeZero;

mainScrollView.showsVerticalScrollIndicator = YES;

mainScrollView.scrollIndicatorInsets = UIEdgeInsetsMake(50.0f, 0, 0, 0);

return mainScrollView;

}

- (UIScrollView *)createHeadScrollView{

UIScrollView *headScrollView = [[UIScrollView alloc] initWithFrame:HEADER_INIT_FRAME];

headScrollView.scrollEnabled = NO;

headScrollView.contentSize = CGSizeMake(320, 1000);

return headScrollView;

}

- (UIImageView *)createBlurImageViewOfView:(UIScrollView *)scrollview{

UIGraphicsBeginImageContextWithOptions(scrollview.bounds.size, scrollview.opaque, 0.0);

[scrollview.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *img = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

UIImageView *blurImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, HEADER_HEIGHT)];

blurImageView.image = [img applyBlurWithRadius:12 tintColor:[UIColor colorWithWhite:0.8 alpha:0.4] saturationDeltaFactor:1.8 maskImage:nil];

blurImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

blurImageView.alpha = 0;

blurImageView.backgroundColor = [UIColor clearColor];

return blurImageView;

}

- (void)scrollDidScrollView:(UIScrollView *)scrollView withMainScrollView:(UIScrollView *)mainScrollView withTableView:(UITableView *)tableView withHeadScrollView:(UIScrollView *)headScrollView withBlurImageView:(UIImageView *)blurImageView{

CGFloat y = 0.0f;

CGRect rect = HEADER_INIT_FRAME;

if (scrollView.contentOffset.y < 0.0f) {

// 下拉变大效果

y = fabs(MIN(0.0f, mainScrollView.contentOffset.y));

headScrollView.frame = CGRectMake(CGRectGetMinX(rect) - y / 2.0f, CGRectGetMinY(rect) - y, CGRectGetWidth(rect) + y, CGRectGetHeight(rect) + y);

}

else {

y = mainScrollView.contentOffset.y;

blurImageView.alpha = MIN(1 , y * kBlurFadeInFactor);

CGFloat backgroundScrollViewLimit = headScrollView.frame.size.height - kBarHeight;

if (y > backgroundScrollViewLimit) {

headScrollView.frame = (CGRect) {.origin = {0, y - headScrollView.frame.size.height + kBarHeight}, .size = {320, HEADER_HEIGHT}};

tableView.frame = (CGRect){.origin = {0, CGRectGetMinY(headScrollView.frame) + CGRectGetHeight(headScrollView.frame)}, .size = tableView.frame.size };

tableView.contentOffset = CGPointMake (0, y - backgroundScrollViewLimit);

CGFloat contentOffsetY = -backgroundScrollViewLimit * kBackgroundParallexFactor;

[headScrollView setContentOffset:(CGPoint){0,contentOffsetY} animated:NO];

}

else {

headScrollView.frame = rect;

tableView.frame = (CGRect){.origin = {0, CGRectGetMinY(rect) + CGRectGetHeight(rect)}, .size = tableView.frame.size };

[tableView setContentOffset:(CGPoint){0,0} animated:NO];

[headScrollView setContentOffset:CGPointMake(0, -y * kBackgroundParallexFactor)animated:NO];

}

}

}

@end

3.main.m

复制代码 代码如下:

#import "RootViewController.h"

#import "CommentCell.h"

#import "MTSecretAppEffect.h"

#define HEADER_HEIGHT 200.0f

@interface RootViewController () <UIScrollViewDelegate, UITableViewDataSource, UITableViewDelegate>

@property (nonatomic,strong) MTSecretAppEffect *secretEffect; // secretApp 效果对象

@property (nonatomic,strong) UIScrollView *mainScrollView; // 与view相同大小的scrollView

@property (nonatomic,strong) UIScrollView *headScrollView; //

@property (nonatomic,strong) UIImageView *blurImageView; //

@property (nonatomic,strong) UITableView *tableView; //

@end

@implementation RootViewController

- (void)viewDidLoad

{

[super viewDidLoad];

// 0.创建SecretApp effect 效果对象

self.secretEffect = [[MTSecretAppEffect alloc] init];

// 1.主底部scrollView

self.mainScrollView = [self.secretEffect createMainScrollView];

self.mainScrollView.delegate = self;

self.view = self.mainScrollView;

// 2.head背景View

self.headScrollView = [self.secretEffect createHeadScrollView];

// 3.背景图片视图

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, HEADER_HEIGHT)];

imageView.image = [UIImage imageNamed:@"secret.png"];

imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

[self.headScrollView addSubview:imageView];

// 4.模糊视图

_blurImageView = [self.secretEffect createBlurImageViewOfView:self.headScrollView];

[self.headScrollView addSubview:_blurImageView];

// 5.tableView

self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, HEADER_HEIGHT, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame) - 50 ) style:UITableViewStylePlain];

self.tableView.scrollEnabled = NO;

self.tableView.delegate = self;

self.tableView.dataSource = self;

self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];

self.tableView.separatorColor = [UIColor clearColor];

// 6.添加视图

[self.view addSubview:self.headScrollView];

[self.view addSubview:self.tableView];

// 7.设置一下

self.mainScrollView.contentSize = CGSizeMake(320, self.tableView.contentSize.height + CGRectGetHeight(self.headScrollView.frame));

}

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

// 8.调用方法

[self.secretEffect scrollDidScrollView:scrollView withMainScrollView:self.mainScrollView withTableView:self.tableView withHeadScrollView:self.headScrollView withBlurImageView:self.blurImageView];

}

#pragma mark - 隐藏状态栏

- (BOOL)prefersStatusBarHidden {

return YES;

}

#pragma mark - UITableView dataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

return 1;

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

return 20;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

return 40;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

CommentCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"Cell %ld", indexPath.row]];

if (!cell) {

cell = [[CommentCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[NSString stringWithFormat:@"Cell %ld", indexPath.row]];

}

cell.textLabel.text = [NSString stringWithFormat:@"section = %ld row = %ld",indexPath.section,indexPath.row];

return cell;

}

- (void)didReceiveMemoryWarning

{

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

@end

效果图:

PPPPPPPPPPPPPPPPPPPPPP1

它主要效果:下拉头部视图放大,上拉视图模糊而且到一定位置固定不动,其他Cell可以继续上移.

封装的主要效果类:MTHeadEffect.m(.h文件省略,很简单的)

复制代码 代码如下:

#import "MTHeadEffect.h"

#import <QuartzCore/QuartzCore.h>

#import <Accelerate/Accelerate.h>

// 屏幕的物理宽度

#define ScreenWidth [UIScreen mainScreen].bounds.size.width

#define HeadViewH 40

CGFloat const kImageOriginHight = 200.f;

@implementation MTHeadEffect

+ (void)viewDidScroll:(UIScrollView *)tableView withHeadView:(UIImageView *)headView withBlur:(CGFloat)blur{

NSLog(@"y = %f",tableView.contentOffset.y);

if (tableView.contentOffset.y > kImageOriginHight - HeadViewH) {

headView.frame = CGRectMake(0, -(kImageOriginHight - HeadViewH), ScreenWidth, kImageOriginHight);

[[UIApplication sharedApplication].keyWindow addSubview:headView];

}else if ((tableView.contentOffset.y < kImageOriginHight - HeadViewH) && tableView.contentOffset.y > 0){

blur = (tableView.contentOffset.y) / 500.0 + 0.45;

headView.image = [[UIImage imageNamed:@"2"] boxblurImageWithBlur:blur];

headView.frame = CGRectMake(0, 0, ScreenWidth, kImageOriginHight);

[tableView addSubview:headView];

}else if (tableView.contentOffset.y <= 0){

// 放大效果---x,y坐标的增量和宽度,高度的增量保持一致

CGFloat offset = -tableView.contentOffset.y;

headView.frame = CGRectMake(-offset,-offset, ScreenWidth+ offset * 2, kImageOriginHight + offset);

headView.image = [[UIImage imageNamed:@"2"] boxblurImageWithBlur:0.01];

}

}

@end

@implementation UIImage (BlurEffect)

// 为高斯模糊效果封装的一个类目

-(UIImage *)boxblurImageWithBlur:(CGFloat)blur {

NSData *imageData = UIImageJPEGRepresentation(self, 1); // convert to jpeg

UIImage* destImage = [UIImage imageWithData:imageData];

if (blur < 0.f || blur > 1.f) {

blur = 0.5f;

}

int boxSize = (int)(blur * 40);

boxSize = boxSize - (boxSize % 2) + 1;

CGImageRef img = destImage.CGImage;

vImage_Buffer inBuffer, outBuffer;

vImage_Error error;

voidvoid *pixelBuffer;

//create vImage_Buffer with data from CGImageRef

CGDataProviderRef inProvider = CGImageGetDataProvider(img);

CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);

inBuffer.width = CGImageGetWidth(img);

inBuffer.height = CGImageGetHeight(img);

inBuffer.rowBytes = CGImageGetBytesPerRow(img);

inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);

//create vImage_Buffer for output

pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));

if(pixelBuffer == NULL)

NSLog(@"No pixelbuffer");

outBuffer.data = pixelBuffer;

outBuffer.width = CGImageGetWidth(img);

outBuffer.height = CGImageGetHeight(img);

outBuffer.rowBytes = CGImageGetBytesPerRow(img);

// Create a third buffer for intermediate processing

voidvoid *pixelBuffer2 = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));

vImage_Buffer outBuffer2;

outBuffer2.data = pixelBuffer2;

outBuffer2.width = CGImageGetWidth(img);

outBuffer2.height = CGImageGetHeight(img);

outBuffer2.rowBytes = CGImageGetBytesPerRow(img);

//perform convolution

error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer2, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);

if (error) {

NSLog(@"error from convolution %ld", error);

}

error = vImageBoxConvolve_ARGB8888(&outBuffer2, &inBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);

if (error) {

NSLog(@"error from convolution %ld", error);

}

error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);

if (error) {

NSLog(@"error from convolution %ld", error);

}

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,

outBuffer.width,

outBuffer.height,

8,

outBuffer.rowBytes,

colorSpace,

(CGBitmapInfo)kCGImageAlphaNoneSkipLast);

CGImageRef imageRef = CGBitmapContextCreateImage (ctx);

UIImage *returnImage = [UIImage imageWithCGImage:imageRef];

//clean up

CGContextRelease(ctx);

CGColorSpaceRelease(colorSpace);

free(pixelBuffer);

free(pixelBuffer2);

CFRelease(inBitmapData);

CGImageRelease(imageRef);

return returnImage;

}

@end

@main.m

复制代码 代码如下:

- (void)viewDidLoad

{

[super viewDidLoad];

// Do any additional setup after loading the view.

// tableView

self.testTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 568) style:UITableViewStylePlain];

self.testTableView.delegate = self;

self.testTableView.dataSource = self;

[self.view addSubview:_testTableView];

/**

* 隐藏状态栏效果

* 1.系统提供了2种动画,一种是偏移,一种是渐隐

* 2.在plist文件中将”View controller-based status bar appearance” 设置为 “No”

*/

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

// headView不作为tableHeadView,而是覆盖在第一个Cell上

self.headView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];

self.headView.image = [[UIImage imageNamed:@"2"] boxblurImageWithBlur:0.01];

self.headView.contentMode = UIViewContentModeScaleAspectFill; // 图片展示全高度

self.headView.clipsToBounds = YES;

[self.testTableView addSubview:self.headView];

}

#pragma mark - scroll delegate 头部视图效果方法

-(void)scrollViewDidScroll:(UIScrollView *)scrollView

{

[MTHeadEffect viewDidScroll:scrollView withHeadView:self.headView withBlur:0.01];

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{

return 1;

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

return 25;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

if (indexPath.row == 0) {

return 200;

}

return 40;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

static NSString *cellIdentf = @"cell";

UITableViewCell *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:cellIdentf];

if (!cell) {

cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentf];

}

cell.textLabel.text = [NSString stringWithFormat:@"section = %ld row = %ld",indexPath.section,indexPath.row];

return cell;

}

效果图:额,不会制作gif动图,所以不太好演示,反正关键代码已经给出,大家可以自己去尝试.

第三方FXBlurView做法的关键代码:

复制代码 代码如下:

- (void)createBlurView{

self.blurView = [[FXBlurView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, kOriginHight)];

self.blurView.tintColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1];

self.blurView.blurRadius = 1.0;

self.blurView.dynamic = YES;

self.blurView.alpha = 0.0;

self.blurView.contentMode = UIViewContentModeBottom;

}

#pragma mark - scroll delegate 头部视图效果方法

-(void)scrollViewDidScroll:(UIScrollView *)scrollView

{

if (scrollView.contentOffset.y > 0) {

self.blurView.alpha = 1.0;

self.blurView.blurRadius = scrollView.contentOffset.y / 4.0;

}

if (scrollView.contentOffset.y == 0) {

self.blurView.alpha = 0.0;

}

if (scrollView.contentOffset.y < 0) {

CGFloat offset = - scrollView.contentOffset.y;

self.blurView.alpha = 0.0;

NSArray *indexPathArray = [self.testTableView indexPathsForVisibleRows];

HMTBlurTableViewCell *blurCell = (HMTBlurTableViewCell *)[self.testTableView cellForRowAtIndexPath:[indexPathArray objectAtIndex:0]];

blurCell.blurImageView.frame = CGRectMake(-offset, -offset, ScreenWidth + offset * 2, kOriginHight + offset);

}

}

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新IOS开发学习
热门IOS开发学习
编程开发子分类