zoukankan      html  css  js  c++  java
  • iOS开发之剖析"秘密"App内容页面效果(一)

               近期在玩"秘密",发现点击主界面的Cell进去后的页面效果不错,就写了个Demo来演示下.

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

    @封装的主要效果类:MTHeadEffect.m(.h文件省略,非常easy的)

    #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);
    
        }
    }
    




  • 相关阅读:
    python模块整理2-sys模块 分类: python Module 2013-09-13 16:49 563人阅读 评论(0) 收藏
    sys常用模块小探 分类: python Module 2013-09-13 16:42 339人阅读 评论(0) 收藏
    先执行linux的clear清屏命令,再执行其他操作 分类: python 小练习 2013-09-13 11:23 441人阅读 评论(0) 收藏
    MySQL 解决ERROR 1045 (28000): Access deniedfor user datam@localhost (using password: YES)的问题 分类: database 2013-09-12 15:52 402人阅读 评论(0) 收藏
    函数名function是一个数据类型,可以赋值 分类: python基础学习 2013-09-12 11:01 366人阅读 评论(0) 收藏
    解决 mysql error: Failed dependencies: 错误 分类: database 2013-09-11 11:23 772人阅读 评论(0) 收藏
    Java之wait()/sleep()和notify()/notifyAll()
    Java之数据流DataInput(Output)Stream 和 字节数组流 ByteArrayInput(Output) Stream的嵌套
    Eclipse的简易教程
    JAVA中的反射机制
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6919757.html
Copyright © 2011-2022 走看看