广

IOS开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

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

    2018-04-03 22:29:54 次阅读 稿源:互联网
    广告

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

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告