iOS开发分析"秘密"App内容页面的效果(两)
@我前几天写的"秘密"的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
@效果图:
版权声明:本文博客原创文章,博客,未经同意,不得转载。
iOS开发分析"秘密"App内容页面的效果(两)的更多相关文章
- 谈谈iOS开发如何写个人中心这类页面--静态tableView页面的编写
本文来自 网易云社区 . 一.本文讲的是什么问题? 在开发 iOS 应用时,基本都会遇到个人中心.设置.详情信息等页面,这里截取了某应用的详情编辑页面和个人中心页面,如下: 我们以页面结构的角度考虑这 ...
- IOS开发之自动布局显示网络请求内容
在上一篇博客中详细的介绍了IOS开发中的相对布局和绝对布局,随着手机屏幕尺寸的改变,在App开发中为了适应不同尺寸的手机屏幕,用自动布局来完成我们想要实现的功能和效果显得尤为重要.本人更喜欢使用相对布 ...
- 【转】【iOS开发】打开另一个APP(URL Scheme与openURL)
目标 平常我们做iOS开发,会经常遇到打开其他的APP的功能.本篇文章讲的就是打开别人的APP的一些知识.我们的目标是: 打开别人的APP 让别人打开我们的APP iOS9的适配问题 使用URL Sc ...
- iOS开发笔记7:Text、UI交互细节、两个动画效果等
Text主要总结UILabel.UITextField.UITextView.UIMenuController以及UIWebView/WKWebView相关的一些问题. UI细节主要总结界面交互开发中 ...
- iOS开发之剖析"秘密"App内容页面效果(一)
近期在玩"秘密",发现点击主界面的Cell进去后的页面效果不错,就写了个Demo来演示下. 它主要效果:下拉头部视图放大,上拉视图模糊并且到一定位置固定不动,其它Cell能够继续上 ...
- iOS开发基础:最新的APP打包上架流程
之前有人留言让我更新部分文章,下面就为大家分享一下iOS的APP打包上架流程: 上传至apple developer 1.1 上传准备工作 更新上架和发布上架不同,在原始版本首次上架的时候就将描述文件 ...
- iOS开发之常用资讯类App的分类展示与编辑的完整案例实现(Swift版)
上篇博客我们聊了<资讯类App常用分类控件的封装与实现(CollectionView+Swift3.0)>,今天的这篇博客就在上篇博客的基础上做些东西.做一个完整的资讯类App中的分类展示 ...
- iOS开发之如何应对苹果app的ipv6时代?
WWDC2015苹果宣布在ios9支持纯IPv6的网络服务,并且要求2016年提交到app store的应用必须兼容纯IPv6的网络,要求适配的系统版本是ios9以上(包括ios9). 一 背景介绍 ...
- iOS开发之一句代码检测APP版本的更新
提示更新效果图如下,当然也是可以自定义类似与AlertView相似的自定义view,如京东.网易云音乐都是自定义了这种提示框的view.以下只展示,从App Store获取到app信息.并解析app信 ...
随机推荐
- 学习通过Thread+Handler实现非UI线程更新UI组件(转)
[Android线程机制] 出于性能考虑,Android的UI操作并不是线程安全的,这就意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的规则 ...
- [原创].NET 分布式架构开发实战之一 故事起源
原文:[原创].NET 分布式架构开发实战之一 故事起源 .NET 分布式架构开发实战之一 故事起源 前言:本系列文章主要讲述一个实实在在的项目开发的过程,主要包含:提出问题,解决问题,架构设计和各个 ...
- Servlet上传文件
Servlet上传文件 1.准备工作 (1)利用FileUpload组件上传文件,须要到apache上下载commons-fileupload-1.3.1.jar 下载地址:http://common ...
- Dapper的使用
轻量型ORM框架Dapper的使用 /// <summary> /// 查询操作 /// </summary> /// <typeparam name="T&q ...
- jqm的多列布局demo,html5的多列布局demo,多列布局的具体解说,html5开发实例具体解释
因为移动设备屏幕宽度较小,所以一般不建议使用多列布局.但有时你可能须要并排放置一些元素(如button之类的). jQuery Mobile通过约定的类名ui-grid来提供了一种基于css的多列布局 ...
- 读改善c#代码157个建议:建议13~15
目录: 建议13:为类型输出格式化字符串 建议14:正确实现浅拷贝和深拷贝 建议15:使用dynamic来简化反射实现 一.建议13:为类型输出格式化字符串 有些类型需要我们根据业务需求提供字符串的格 ...
- [6] 算法路 - 双向冒泡排序的Shaker
Shaker序列 –算法 1. 气泡排序的双向进行,先让气泡排序由左向右进行.再来让气泡排序由右往左进行,如此完毕一次排序的动作 2. 使用left与right两个旗标来记录左右两端已排序的元素位置. ...
- WPF:警惕TextBox会占用过多内存
原文:WPF:警惕TextBox会占用过多内存 问题源自这篇文章:WPF的TextBox产生内存泄露的情况. 整个问题是这样的,文章作者演示使用类似下方的代码来不停地像WPF的TextBox控件赋值: ...
- 一个简单的Java死锁示例(转)
在实际编程中,要尽量避免出现死锁的情况,但是让你故意写一个死锁的程序时似乎也不太简单(有公司会出这样的面试题),以下是一个简单的死锁例子,程序说明都写着类的注释里了,有点罗嗦,但是应该也还是表述清楚了 ...
- msys2 安装注意事项
它一直在使用 msys.有一个最近发现 msys2.而且msys2 配套的编译器是MinGW-w64. 就试着用了用,感觉还不错,这里把安装过程记录一下. 简单的说,MSYS2 是MSYS的一个升级版 ...