iOS-TwitterCover小效果

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

For What?

Twitter客户端在个人Tab有这样的一个效果:

向下拖动ScrollView(TableView)时,ScrollView上方的图片会随着手指的拖动而放大并且变模糊。松开手指之后,图片随着ScrollView的回复原来位置而恢复原样,如上图。

What I Do?

So,我们可以怎么实现一个类似的效果呢?

下面是我刚写的一个Demo截图,非常简单,而且也是用了网上开源的毛玻璃代码。

咱来个高端的工具,看看,这里面是怎么的一个架构?!

通过树状的视图效果,我们可以看出,背景图片backgroundImageView(放大,毛玻璃效果)是一个UIImageView的子类,TableView会占据真个Window的bounds。其中TableView的tableHeaderView正好覆盖在backgroundImageView的上方,并且背景是透明色,才能看到下层backgroundImageView的变化情况。

依赖开源代码

毛玻璃图片开源代码:https://github.com/CoCrash/DKLiveBlur

1//2//DKLiveBlurView.h3//LiveBlur4//5//Created by Dmitry Klimkin on 16/6/13.6//Copyright (c) 2013 Dmitry Klimkin. All rights reserved.7//89#import<UIKit/UIKit.h>1011#definekDKBlurredBackgroundDefaultLevel 0.9f12#definekDKBlurredBackgroundDefaultGlassLevel 0.2f13#definekDKBlurredBackgroundDefaultGlassColor [UIColor whiteColor]1415@interfaceDKLiveBlurView : UIImageView1617@PRoperty (nonatomic, strong) UIImage *originalImage;18@property (nonatomic, weak) UIScrollView *scrollView;19@property (nonatomic, assign)floatinitialBlurLevel;20@property (nonatomic, assign)floatinitialGlassLevel;21@property (nonatomic, assign) BOOL isGlassEffectOn;22@property (nonatomic, strong) UIColor *glassColor;2324- (void)setBlurLevel:(float)blurLevel;2526@end

DKLiveBlurView.h

1//2//DKLiveBlurView.m3//LiveBlur4//5//Created by Dmitry Klimkin on 16/6/13.6//Copyright (c) 2013 Dmitry Klimkin. All rights reserved.7//89#import"DKLiveBlurView.h"10#import<Accelerate/Accelerate.h>1112@interfaceDKLiveBlurView ()1314@property (nonatomic, strong) UIImageView *backgroundImageView;15@property (nonatomic, strong) UIView *backgroundGlassView;1617@end1819@implementationDKLiveBlurView2021@synthesizeoriginalImage =_originalImage;22@synthesizebackgroundImageView =_backgroundImageView;23@synthesizescrollView =_scrollView;24@synthesizeinitialBlurLevel =_initialBlurLevel;25@synthesizebackgroundGlassView =_backgroundGlassView;26@synthesizeinitialGlassLevel =_initialGlassLevel;27@synthesizeisGlassEffectOn =_isGlassEffectOn;28@synthesizeglassColor =_glassColor;2930- (id)initWithFrame:(CGRect)frame {31self =[super initWithFrame:frame];32if(self) {33//Initialization code3435_initialBlurLevel =kDKBlurredBackgroundDefaultLevel;36_initialGlassLevel =kDKBlurredBackgroundDefaultGlassLevel;37_glassColor =kDKBlurredBackgroundDefaultGlassColor;3839_backgroundImageView =[[UIImageView alloc] initWithFrame: self.bounds];4041_backgroundImageView.alpha =0.0;42_backgroundImageView.contentMode =UIViewContentModeScaleToFill;43_backgroundImageView.backgroundColor =[UIColor clearColor];4445_backgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;4647[self addSubview: _backgroundImageView];4849_backgroundGlassView =[[UIView alloc] initWithFrame: self.bounds];5051_backgroundGlassView.alpha =0.0;52_backgroundGlassView.backgroundColor =kDKBlurredBackgroundDefaultGlassColor;5354_backgroundGlassView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;5556[self addSubview: _backgroundGlassView];57}58returnself;59}6061- (void)setGlassColor:(UIColor *)glassColor {62_glassColor =glassColor;63_backgroundGlassView.backgroundColor =glassColor;64}6566- (void)setScrollView:(UIScrollView *)scrollView {67[_scrollView removeObserver: self forKeyPath:@"contentOffset"];6869_scrollView =scrollView;7071[_scrollView addObserver: self forKeyPath:@"contentOffset"options:0context: nil];72}7374- (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur {75if((blur <0.0f) || (blur >1.0f)) {76blur =0.5f;77}7879intboxSize = (int)(blur *100);80boxSize -= (boxSize %2) +1;8182CGImageRef img =image.CGImage;8384vImage_Buffer inBuffer, outBuffer;85vImage_Error error;86void*pixelBuffer;8788CGDataProviderRef inProvider =CGImageGetDataProvider(img);89CFDataRef inBitmapData =CGDataProviderCopyData(inProvider);9091inBuffer.width =CGImageGetWidth(img);92inBuffer.height =CGImageGetHeight(img);93inBuffer.rowBytes =CGImageGetBytesPerRow(img);94inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);9596pixelBuffer = malloc(CGImageGetBytesPerRow(img) *CGImageGetHeight(img));9798outBuffer.data =pixelBuffer;99outBuffer.width =CGImageGetWidth(img);100outBuffer.height =CGImageGetHeight(img);101outBuffer.rowBytes =CGImageGetBytesPerRow(img);102103error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL,1040,0, boxSize, boxSize, NULL,105kvImageEdgeExtend);106107108if(error) {109NSLog(@"error from convolution %ld", error);110}111112CGColorSpaceRef colorSpace =CGColorSpaceCreateDeviceRGB();113CGContextRef ctx =CGBitmapContextCreate(114outBuffer.data,115outBuffer.width,116outBuffer.height,1178,118outBuffer.rowBytes,119colorSpace,120CGImageGetBitmapInfo(image.CGImage));121122CGImageRef imageRef =CGBitmapContextCreateImage (ctx);123UIImage *returnImage =[UIImage imageWithCGImage:imageRef];124125//clean up126CGContextRelease(ctx);127CGColorSpaceRelease(colorSpace);128129free(pixelBuffer);130CFRelease(inBitmapData);131132CGColorSpaceRelease(colorSpace);133CGImageRelease(imageRef);134135returnreturnImage;136}137138- (void)setOriginalImage:(UIImage *)originalImage {139_originalImage =originalImage;140141self.image =originalImage;142143dispatch_queue_t queue = dispatch_queue_create("Blur queue", NULL);144145dispatch_async(queue, ^{146147UIImage *blurredImage =[self blurryImage: self.originalImage withBlurLevel: self.initialBlurLevel];148149dispatch_async(dispatch_get_main_queue(), ^{150151self.backgroundImageView.alpha =0.0;152self.backgroundImageView.image =blurredImage;153});154});155156dispatch_release(queue);157}158159- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object160change:(NSDictionary *)change context:(void*)context {161162//closer to zero, less blur applied163[self setBlurLevel:(self.scrollView.contentInset.top - self.scrollView.contentOffset.y) / (3* CGRectGetHeight(self.bounds) /5)];164}165166- (void)setBlurLevel:(float)blurLevel {167self.backgroundImageView.alpha =blurLevel;168169if(self.isGlassEffectOn) {170self.backgroundGlassView.alpha = MAX(0.0, MIN(self.backgroundImageView.alpha -self.initialGlassLevel, self.initialGlassLevel));171}172}173174@end

DKLiveBlurView.m

其实可以不用开DKLiveBlur的开源Demo,他主要实现了UIImageView的一个子类DKLiveBlurView,增加了毛玻璃效果。

- setBlurLevel:方法给我们有能力去设置毛玻璃的程度,这也是我们实现类似Twitter cover效果的主要效果,毛玻璃效果随着tableview的偏移程度,逐渐改变的过程。

我又写了几行代码?

为了实现这个效果,我又写了几行代码?

用户在拖动scrollView(tableView)导致content offset改变的时候就会调用-scrollViewDidScroll:方法,因此我们想在用户拖动scrollview的时候,改变背景图片的大小和毛玻璃程度,则需要实现-scrollViewDidScroll:方法,并计算scrollview的content offset在Y轴下的改变值,得到图片伸缩和毛玻璃效果的比例。

除了做这个界面的布局代码,实际有用的代码就这几行:

1- (void)scrollViewDidScroll:(UIScrollView *)scrollView{2CGPoint offset1 =scrollView.contentOffset;3[backgroundView setBlurLevel:(- offset1.y/120)];45CGRect baseFrame =backgroundView.frame;6floatvisable_height =162-offset1.y;7if(visable_height >160) {8//放大的情况9baseFrame.origin.y =0;10baseFrame.size.height =visable_height;11}else{12//正常情况13baseFrame.origin.y = (visable_height -160)/2.0f;14baseFrame.size.height =160;15}16backgroundView.frame =baseFrame;1718}

国内还有哪些高端大气的APP用了类似的效果?

看到这个界面大家是不是很熟悉?哈哈,陌陌同学的个人资料页就有类似的一个效果,不过TA平凡点,没有毛玻璃效果。或者毛玻璃有点像打马赛克一样,让陌陌同学很是不适吧。

曾记否,TX的手Q小企鹅也有过一个小小界面是用了类似的效果的。我相信是个大家都未曾听说过的东东:公开群···

在TA的资料页也是用了类似偏移缩放的效果。现在公开群的入口貌似被老大们屏蔽了,那就算TA已经挂掉了吧,这里我们就没办法截取效果图给大家看了。

SO,你看,那么多人喜欢用到这个效果,行过路过,别忘了进来看看哈。哈哈。Daisy,我写博客了···

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航