SoFunction
Updated on 2025-04-10

Implementation of pull-down zoom-in and pull-up blur of views in iOS development

Put the overall view of the "secret" Cell effect into the scrollView, which is basically the same as the secret app.
The code is as follows: (I won’t write a class with fuzzy effects. You can search for "UIImage+ImageEffects" and import it.)

Copy the codeThe code is as follows:

#import <Foundation/> 
 
@interface MTSecretAppEffect : NSObject 
 
/**
*  Create a whole scrollView, load all the headScrollView and tableView on it, and slide up and down, and all the other slides are prohibited
 *
 *  @return mainScrollView
 */ 
- (UIScrollView *)createMainScrollView; 
 
/**
*  Create headScrollView
 *
 *  @return headScrollView
 */ 
- (UIScrollView *)createHeadScrollView; 
 
/**
* Create a blurred view of the head
 *
 *  @param scrollview headScrollView
 *
 *  @return blurImageView
 */ 
- (UIImageView *)createBlurImageViewOfView:(UIScrollView *)scrollview; 
 
/**
*  Methods called in - (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 



Copy the codeThe code is as follows:

#import "" 
#import "UIImage+" 
#import <QuartzCore/> 
 
#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 
 
// Deficiency: The caller sets up a proxy
- (UIScrollView *)createMainScrollView{ 
 
// Bottom ScrollView of the same size
    UIScrollView *mainScrollView = [[UIScrollView alloc] initWithFrame:[UIApplication sharedApplication].]; 
    = YES; 
    = YES; 
    = CGSizeZero; 
    = YES; 
    = UIEdgeInsetsMake(50.0f, 0, 0, 0); 
 
    return mainScrollView; 
     

 
- (UIScrollView *)createHeadScrollView{ 
 
    UIScrollView *headScrollView = [[UIScrollView alloc] initWithFrame:HEADER_INIT_FRAME]; 
    = NO; 
    = CGSizeMake(320, 1000); 
     
    return headScrollView; 

 
- (UIImageView *)createBlurImageViewOfView:(UIScrollView *)scrollview{ 
 
    UIGraphicsBeginImageContextWithOptions(, , 0.0); 
    [ renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    UIImageView *blurImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, HEADER_HEIGHT)]; 
    = [img applyBlurWithRadius:12 tintColor:[UIColor colorWithWhite:0.8 alpha:0.4] saturationDeltaFactor:1.8 maskImage:nil]; 
    = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
    = 0; 
    = [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 ( < 0.0f) { 
// Pull down to increase the effect
        y = fabs(MIN(0.0f, )); 
        = CGRectMake(CGRectGetMinX(rect) - y / 2.0f, CGRectGetMinY(rect) - y, CGRectGetWidth(rect) + y, CGRectGetHeight(rect) + y); 
         
    } 
    else { 
         
        y = ; 
        = MIN(1 , y * kBlurFadeInFactor); 
        CGFloat backgroundScrollViewLimit = - kBarHeight; 
         
        if (y > backgroundScrollViewLimit) { 
            = (CGRect) {.origin = {0, y - + kBarHeight}, .size = {320, HEADER_HEIGHT}}; 
            = (CGRect){.origin = {0, CGRectGetMinY() + CGRectGetHeight()}, .size = }; 
            = CGPointMake (0, y - backgroundScrollViewLimit); 
            CGFloat contentOffsetY = -backgroundScrollViewLimit * kBackgroundParallexFactor; 
            [headScrollView setContentOffset:(CGPoint){0,contentOffsetY} animated:NO]; 
        } 
        else { 
            = rect; 
            = (CGRect){.origin = {0, CGRectGetMinY(rect) + CGRectGetHeight(rect)}, .size = }; 
            [tableView setContentOffset:(CGPoint){0,0} animated:NO]; 
            [headScrollView setContentOffset:CGPointMake(0, -y * kBackgroundParallexFactor)animated:NO]; 
        } 
    } 
 

 
@end 



Copy the codeThe code is as follows:

#import "" 
#import "" 
#import "" 
 
#define HEADER_HEIGHT 200.0f 
 
@interface RootViewController () <UIScrollViewDelegate, UITableViewDataSource, UITableViewDelegate> 
 
@property (nonatomic,strong) MTSecretAppEffect *secretEffect;     // secretApp effect object
@property (nonatomic,strong) UIScrollView *mainScrollView;           // ScrollView of the same size as the view
@property (nonatomic,strong) UIScrollView *headScrollView;        // 
@property (nonatomic,strong) UIImageView  *blurImageView;         // 
@property (nonatomic,strong) UITableView *tableView;              // 
 
@end 
 
@implementation RootViewController 
 
- (void)viewDidLoad 

    [super viewDidLoad]; 
     
     
// 0. Create SecretApp effect object
    = [[MTSecretAppEffect alloc] init]; 
// 1. Main bottom scrollView
    = [ createMainScrollView]; 
    = self; 
    = ; 
// Background View
    = [ createHeadScrollView]; 
// 3. Background picture view
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, HEADER_HEIGHT)]; 
    = [UIImage imageNamed:@""]; 
    = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
    [  addSubview:imageView]; 
// 4. Blur view
    _blurImageView = [ createBlurImageViewOfView:]; 
    [ addSubview:_blurImageView]; 
    //  
    = [[UITableView alloc] initWithFrame:CGRectMake(0, HEADER_HEIGHT, CGRectGetWidth(), CGRectGetHeight() - 50 ) style:UITableViewStylePlain]; 
    = NO; 
    = self; 
    = self; 
    = [[UIView alloc] initWithFrame:CGRectZero]; 
    = [UIColor clearColor]; 
// 6. Add a view
    [ addSubview:]; 
    [ addSubview:]; 
// 7. Set it up
    = CGSizeMake(320, + CGRectGetHeight()); 
 

 
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 
     
// 8. Calling method
    [ scrollDidScrollView:scrollView withMainScrollView: withTableView: withHeadScrollView: withBlurImageView:]; 

 
 
#pragma mark - Hide status bar
- (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", ]]; 
    if (!cell) { 
        cell = [[CommentCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[NSString stringWithFormat:@"Cell %ld", ]]; 
    } 
    = [NSString stringWithFormat:@"section = %ld row = %ld",,]; 
 
    return cell; 

 
- (void)didReceiveMemoryWarning 

    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 

 
@end  
                
Reproduction picture:
PPPPPPPPPPPPPPPPPPPPPP1
Its main effect: the head view of the pull-down is enlarged, the pull-up view is blurred and fixed to a certain position, and other cells can continue to move upward.
The main effect of encapsulation: (.h file is omitted, very simple)

Copy the codeThe code is as follows:

#import "" 
#import <QuartzCore/> 
#import <Accelerate/> 
 
// The physical width of the screen
#define ScreenWidth  [UIScreen mainScreen]. 
#define HeadViewH  40 
 
CGFloat const kImageOriginHight = ; 
 
@implementation MTHeadEffect 
 
+ (void)viewDidScroll:(UIScrollView *)tableView withHeadView:(UIImageView *)headView withBlur:(CGFloat)blur{ 
 
    NSLog(@"y = %f",); 
    if ( > kImageOriginHight - HeadViewH) { 
         
        = CGRectMake(0, -(kImageOriginHight - HeadViewH), ScreenWidth, kImageOriginHight); 
        [[UIApplication sharedApplication].keyWindow addSubview:headView]; 
         
    }else if (( < kImageOriginHight - HeadViewH) && > 0){ 
         
        blur = () / 500.0 + 0.45; 
        = [[UIImage imageNamed:@"2"] boxblurImageWithBlur:blur]; 
        = CGRectMake(0, 0, ScreenWidth, kImageOriginHight); 
        [tableView addSubview:headView]; 
         
    }else if ( <= 0){ 
         
// Zoom effect --- the increments of x,y coordinates and width and height are consistent
        CGFloat offset  = -; 
        = CGRectMake(-offset,-offset, ScreenWidth+ offset * 2, kImageOriginHight + offset); 
        = [[UIImage imageNamed:@"2"] boxblurImageWithBlur:0.01]; 
    } 
     

 
@end 
 
@implementation UIImage (BlurEffect) 
 
// A category for Gaussian blur effect encapsulation
-(UIImage *)boxblurImageWithBlur:(CGFloat)blur { 
     
    NSData *imageData = UIImageJPEGRepresentation(self, 1); // convert to jpeg 
    UIImage* destImage = [UIImage imageWithData:imageData]; 
     
     
    if (blur < || blur > ) { 
        blur = 0.5f; 
    } 
    int boxSize = (int)(blur * 40); 
    boxSize = boxSize - (boxSize % 2) + 1; 
     
    CGImageRef img = ; 
     
    vImage_Buffer inBuffer, outBuffer; 
     
    vImage_Error error; 
     
    voidvoid *pixelBuffer; 
     
     
    //create vImage_Buffer with data from CGImageRef 
     
    CGDataProviderRef inProvider = CGImageGetDataProvider(img); 
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider); 
     
     
    = CGImageGetWidth(img); 
    = CGImageGetHeight(img); 
    = CGImageGetBytesPerRow(img); 
     
    = (void*)CFDataGetBytePtr(inBitmapData); 
     
    //create vImage_Buffer for output 
     
    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img)); 
     
    if(pixelBuffer == NULL) 
        NSLog(@"No pixelbuffer"); 
     
    = pixelBuffer; 
    = CGImageGetWidth(img); 
    = CGImageGetHeight(img); 
    = CGImageGetBytesPerRow(img); 
     
    // Create a third buffer for intermediate processing 
    voidvoid *pixelBuffer2 = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img)); 
    vImage_Buffer outBuffer2; 
    = pixelBuffer2; 
    = CGImageGetWidth(img); 
    = CGImageGetHeight(img); 
    = 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(, 
                                             , 
                                             , 
                                             8, 
                                             , 
                                             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 

@

Copy the codeThe code is as follows:

- (void)viewDidLoad 

    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    // tableView 
    = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 568) style:UITableViewStylePlain]; 
    = self; 
    = self; 
    [ addSubview:_testTableView]; 
     
    /**
*  Hide status bar effect
*  1. The system provides two types of animations, one is offset and the other is fading
*  2. Set "View controller-based status bar appearance" to "No" in the plist file
     */ 
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; 
     
// The headView is not used as a tableHeadView, but is overlaid on the first cell.
    = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)]; 
    = [[UIImage imageNamed:@"2"] boxblurImageWithBlur:0.01]; 
= UIViewContentModeScaleAspectFill;  //  Full height of picture display
    = YES; 
    [ addSubview:]; 
     

 
#pragma mark - scroll delegate head view effect method
-(void)scrollViewDidScroll:(UIScrollView *)scrollView 

     
    [MTHeadEffect viewDidScroll:scrollView withHeadView: 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 ( == 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]; 
    } 
    = [NSString stringWithFormat:@"section = %ld row = %ld",,]; 
    return cell; 
 

Reproduction: Well, I can't make gif animations, so it's not easy to demonstrate. Anyway, the key code has been given, so everyone can try it yourself.
Key code for third-party FXBlurView practices:

Copy the codeThe code is as follows:

- (void)createBlurView{ 
 
    = [[FXBlurView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, kOriginHight)]; 
    = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; 
    = 1.0; 
    = YES; 
    = 0.0; 
    = UIViewContentModeBottom; 
 

 
#pragma mark - scroll delegate head view effect method
-(void)scrollViewDidScroll:(UIScrollView *)scrollView 

     
    if ( > 0) { 
        
        = 1.0; 
        = / 4.0; 
    } 
    if ( == 0) { 
        = 0.0; 
    } 
    if ( < 0) { 
         
        CGFloat offset = - ; 
        = 0.0; 
        NSArray *indexPathArray = [ indexPathsForVisibleRows]; 
        HMTBlurTableViewCell *blurCell = (HMTBlurTableViewCell *)[ cellForRowAtIndexPath:[indexPathArray objectAtIndex:0]]; 
        = CGRectMake(-offset, -offset, ScreenWidth + offset * 2, kOriginHight + offset); 
 
    }