把"秘密"的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
#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
#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
#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); } }
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。