iOS开发中视图的下拉放大和上拉模糊的效果实现

把"秘密"的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);        }  } 

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