Home>

The overall view of the "secret" cell effect is placed in scrollview, which is basically the same effect as the secret app.

The code is as follows:(The class of the blur effect is not written,You can search for "uiimage + imageeffects" and import accelerate.framework)

1.mtsecretappeffect.h

</p>
<p>
#import<foundation/foundation.h>
@interface mtsecretappeffect:nsobject
/**
* Create an overall scrollview, load both headscrollview and tableview on it,Rely on it to slide up and down,All other slides are prohibited
*
* @return mainscrollview
* /
-(uiscrollview *) createmainscrollview;
/**
* Create a headscrollview
*
* @return headscrollview
* /
-(uiscrollview *) createheadscrollview;
/**
* Create a fuzzy view of the head
*
* @param scrollview headscrollview
*
* @return blurimageview
* /
-(uiimageview *) createblurimageviewofview:(uiscrollview *) scrollview;
/**
* Method 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
</p>
<p>

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
//missing:caller sets proxy
-(uiscrollview *) createmainscrollview {
 //bottom scrollview of the same size as self.view
 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) {
 //pull down becomes larger
 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&background;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
</p>
<p>

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 effect object
@property (nonatomic, strong) uiscrollview * mainscrollview;//scrollview of the same size as 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 effect object
 self.secreteffect=[[mtsecretappeffect alloc] init];
 //1. main bottom scrollview
 self.mainscrollview=[self.secreteffect createmainscrollview];
 self.mainscrollview.delegate=self;
 self.view=self.mainscrollview;
 //2.head background view
 self.headscrollview=[self.secreteffect createheadscrollview];
 //3. background image view
 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. fuzzy view
 _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.Add view
 [self.view addsubview:self.headscrollview];
 [self.view addsubview:self.tableview];
 //7.Set it up
 self.mainscrollview.contentsize=cgsizemake (320, self.tableview.contentsize.height + cgrectgetheight (self.headscrollview.frame));
}
-(void) scrollviewdidscroll:(uiscrollview *) scrollview {
 //8.Call method
 [self.secreteffect scrolldidscrollview:scrollview withmainscrollview:self.mainscrollview withtableview:self.tableview withheadscrollview:self.headscrollview withblurimageview:self.blurimageview];
}
#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", 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

Effect picture:

pppppppppppppppppppppppp1

Its main effect:pull down the head view to zoom in,The pull-up view is blurred and fixed to a certain position.Other cells can continue to move up.

Encapsulated main effect class:mtheadeffect.m (.h file omitted,Very simple)

#import "mtheadeffect.h"
#import<quartzcore/quartzcore.h>
#import<accelerate/accelerate.h>
//physical width of the screen
#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) {
 //zoom-in effect --- x and y increments and widths,Consistent increase in height
 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)
//A category encapsulated for Gaussian blur effect
-(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
</p>
<p>

@ 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];
 /**
 * Hide status bar effect
 * 1. The system provides 2 types of animation, one is offset,One is fading
 * 2. Set "view controller-based status bar appearance" to "no" in the plist file
 * /
 [[uiapplication sharedapplication] setstatusbarhidden:yes withanimation:uistatusbaranimationnone];
 //headview is not used as a tableheadview, but is overlaid on the first cell
 self.headview=[[uiimageview alloc] initwithframe:cgrectmake (0, 0, 320, 200)];
 self.headview.image=[[uiimage imagenamed:@"2"] boxblurimagewithblur:0.01];
 self.headview.contentmode=uiviewcontentmodescaleaspectfill;//full height of picture
 self.headview.clipstobounds=yes;
 [self.testtableview addsubview:self.headview];
}
#pragma mark-scroll delegate head view effect method
-(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 [email protected]"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;
}
</p>
<p>

Effect picture:Um, no gif animation is made, so it is not easy to demonstrate,Anyway the key code has been given,You can try it yourself.

Key code for third-party fxblurview practices:

</p>
<p>
-(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 head view effect method
-(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);
 }
}
</p>
<p>
ios
  • Previous JS picture thumbnail with carousel effect code sharing
  • Next ASPNET MVC5 Website Development Framework Model, Data Storage, Business Logic (3)