最近在玩"祕密",發現點擊主界面的Cell進去後的頁面效果不錯,就寫了個Demo來演示下.
它主要效果:下拉頭部視圖放大,上拉視圖模糊而且到一定位置固定不動,其他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;
void *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
void *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);
}
}