独立开发一个APP

独立开发一个社群APP,类似微博,知识星球,简书这一类的。

首先是整个项目的框架的搭建。

中间层的路由跳转方案

抽象出一个中间层来对纷乱的引用关系进行统一的跳转。模块只和中间层耦合,模块间解耦;中间层使用runtime的形式调用模块的业务组件,不依赖具体的模块代码.两种主流方案:

  1. JLRoutes为代表的URLRoute方案:以URL为key,以待执行的block为value,保存在一个全局map中,在内存中常驻;
  2. Mediator中间人方案:把所有的调用都集合在一起,使用一个中间人管理。所有调用方都通过中间人调取另外一个模块;
  • 创建Target-Action。Target对象暴露整个模块对外提供的所有服务,此外,因为Mediator和Target是通过Runtime交互的,Target暴露的方法中接收的参数是一个字典,但在方法实现中负责将传过来的字典还原成各个参数,并调用该模块具体的类和方法。
  • 创建 CTMediator 的Category. 受限于runtime只能以字典形式传一系列参数,Mediator分类的职责就在于对外提供参数友好型的一系列方法,但在方法实现中包装成字典形式。这里涉及到key的定义必须和Target中还原时的key定义一致,因此划分给相同的开发维护。
    使用方法
  1. 结合URLRoute和Mediator的跳转方案

整体导航条Navigation

写自定义的navigationController,主要用于处理问题:

  • 手势返回的支持和不支持。
  • 导航栏的显示和隐藏。
  • 底部tabBar的显示和隐藏。

在一些页面对于statusBar的处理,设置statusBar的背景颜色和样式

网络层

在AFN上面封装,包装AFNManager,创建一个单例的HTTPClient继承自AFHTTPSessionManager,在单例中设置securityPolicy、requestSerializer、responseSerializer、和请求头,以及Content-type相关的参数,包装GET、post请求
没有判断网络的情况,是WIFI还是4G还是3G,还是无网络的状态

tableView自适应

方法一

Sunny写的优化UITableViewCell高度计算的那些事
UITableView+FDTemplateLayoutCell

方法二

SDAutoLayout
不仅可以实现tableview和cell高度自适应,还可以实现普通view的自动布局,比用masonry代码更少,

方法三

在每个元素的模型model中添加一个height属性,实现它的get方法,在get方法中计算需要多行显示文字的高度,然后再加上其他乱七八糟的高度并返回,然后在tableview的

  • (CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath中获取到每行对应的model,取出其中的model.height属性的值返回,还要在cell中确定cell中label的高度。。。总之就是很麻烦,而且还不一定总能算的很正确,甚是受此困扰。

只要你懂一定的Autolayout知识的话,原来实现这种的cell高度自适应,其实是灰常灰常简单的:
首先,第一步,现在自定义的cell中将高度随着内容动态改变的label的布局使用autolayout布局完成,这里有个注意点就是label和cell边界的距离要确定好,不能固定死label的高度,然后设置label的numberOfLines=0,行数设置为0即意味着label可以有任意行。
其次,实现以下两个tableview的delegate中的方法:

1
2
3
4
5
6
7
8
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 10;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}

是的,只要实现这两个方法,然后运行你的项目,你会惊讶的发现,哇塞,高度完美自适应…
这里有几个关键点:
关键点1:必须重写estimatedHeightForRowAtIndexPath方法
这个方法是iOS7.0之后才出现的,如果不重写此方法,仅重写heightForRowAtIndexPath,那么大家会发现,cell并不会根据label的内容,自适应高度。因为系统是先获取cell的高度,再获取cell的view。也就是先调用heightForRowAtIndexPath,再调用cellForRowAtIndexPath。在cellForRowAtIndexPath被调用之前,你的label是没有被设置文本内容的,因此它获取到的高度,并不是你想要的。那么我们必须想办法让系统在获取了cell之后,再获取cell的高度。方法就是,重写estimatedHeightForRowAtIndexPath,顾名思义,它会返回一个估计高度,有了这个方法后,tableview会先调用它获取估计高度,然后获取cell,最后获取真实高度。estimatedHeightForRowAtIndexPath的返回值可以随意,返回多少都可以,只是给tableview一个安慰而已,让它延迟获取真实的高度。
关键点2:真实高度返回值为
UITableViewAutomaticDimension
关键点3:cell中的元素,必须相对于cell的顶部和底部布局,这样在元素中的内容动态变化的时候,才能撑开cell

方法四

ASDK:AsyncDisplayKit.相关连接:
使用 ASDK 性能调优 - 提升 iOS 界面的渲染性能

iOS开发之多种Cell高度自适应实现方案的UI流畅度分析

方法五

iOS 保持界面流畅的技巧

YYKit的

整体的方法

页面布局:masonry自动布局
页面的网络解析:YYModel
页面的网络请求:

各个模块需要注意的问题:

登录模块

第一次登录和再次登录

图片处理

图片压缩

弹框处理

时间处理

下拉刷新和上拉加载更多

第三方登录和第三方分享

第三方分享:

  1. 申请微信APPKey和申请友盟APPkey
  2. cocospod: pod ‘UMengUShare/Social/WeChat’
  3. 在APPdelegate中设置APPkey
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (void)setAppkey
{
//友盟
[WXApi registerApp:WXAPPID];
//设置友盟appkey
[[UMSocialManager defaultManager] setUmSocialAppkey:UMKey];
//分享到微信
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_WechatSession appKey:APPKEY appSecret:APPSECRET redirectURL:@"www.com"];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
BOOL result = [UMSocialSnsService handleOpenURL:url];
return result;
}
  1. 设置Plis跳转的URL。URL Schemes列为白名单
1
2
3
4
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
</array>
  1. 创建分享信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 //创建分享消息对象
UMSocialMessageObject *messageObject = [UMSocialMessageObject messageObject];
NSString *title = self.shareTitle;
NSString *url = self.originUrl;
NSString *text = self.shareText;
NSString *imgUrl = self.shareImage;
UMShareWebpageObject *shareObject = [UMShareWebpageObject shareObjectWithTitle:title descr:text thumImage:imgUrl];
[shareObject setWebpageUrl:url];
messageObject.shareObject = shareObject;
[[UMSocialManager defaultManager] shareToPlatform:UMSocialPlatformType_WechatSession
messageObject:messageObject
currentViewController:nil
completion:^(id data, NSError *error) {
if (error) {
UMSocialLogInfo(@"************Share fail with error %@*********",error);
}else{
if ([data isKindOfClass:[UMSocialShareResponse class]]) {
UMSocialShareResponse *resp = data; UMSocialLogInfo(@"response message is %@",resp.message); UMSocialLogInfo(@"response originalResponse data is %@",resp.originalResponse);}else{ UMSocialLogInfo(@"response data is %@",data); }}
}];

系统问题

启动图

横屏

推送

3Dtouch

屏幕适配

打包问题

1。手动打包

2。自动化打包

优化

  1. tableView的流畅:没有网络请求结束的时候先加载占位图,然后
    UITableView的优化策略
    iOS 开发一定要尝试的 Texture(ASDK)
    UITableView的回调顺序是先多次调用tableView:heightForRowAtIndexPath:以确定 contentSize及Cell的位置,然后才会调用tableView:cellForRowAtIndexPath:,从而来显示在 当前屏幕的Cell。

UITableView的滚动优化主要在于以下两个方面:

减少cellForRowAtIndexPath代理中的计算量(cell的内容计算)
减少heightForRowAtIndexPath代理中的计算量(cell的高度计算)

减少cellForRowAtIndexPath代理中的计算量

首先要提前计算每个cell中需要的一些基本数据,代理调用的时候直接取出;
图片要异步加载,加载完成后再根据cell内部UIImageView的引用设置图片;
图片数量多时,图片的尺寸要跟据需要提前经过transform矩阵变换压缩好(直接设置图片的contentMode让其自行压缩仍然会影响滚动效率),必要的时候要准备好预览图和高清图,需要时再加载高清图。
图片的‘懒加载’方法,即延迟加载,当滚动速度很快时避免频繁请求服务器数据。
尽量手动Drawing视图提升流畅性,而不是直接子类化UITableViewCell,然后覆盖drawRect方法,因为cell中不是只有一个contentview。绘制cell不建议使用UIView,建议使用CALayer。原因要参考UIView和CALayer的区别和联系。

减少heightForRowAtIndexPath代理中的计算量

由于每次TableView进行update更新都会对每一个cell调用heightForRowAtIndexPath代理取得最新的height,会大大增加计算时间。如果表格的所有cell高度都是固定的,那么去掉heightForRowAtIndexPath代理,直接设置TableView的rowHeight属性为固定的高度;
如果高度不固定,应尽量将cell的高度数据计算好并储存起来,代理调用的时候直接取,即将height的计算时间复杂度降到O(1)。例如:在异步请求服务器数据时,提前将cell高度计算好并作为dataSource的一个数据存到数据库供随时取用。

数据刷新

tableView的数据刷新

那就在每个元素的model里面加上一个高度字段,显示的时候如果高度非0,直接拿过来使用,如果是0就自适应计算一下

iOS应用架构谈 组件化方案

把模块拆分成Pod

其他问题

UIScrollView的左右滑动与侧滑返回并存

侧滑返回效果的触发需要满足:(1) 滑动位置在屏幕左边缘;(2)向右滑动;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#pragma mark - 侧滑返回和控件手势冲突的解决方法
//是否支持多手势触发,返回YES,则可以多个手势一起触发方法,返回NO则为互斥.
//是否允许多个手势识别器共同识别,一个控件的手势识别后是否阻断手势识别继续向下传播,默认返回NO;如果为YES,响应者链上层对象触发手势识别后,如果下层对象也添加了手势并成功识别也会继续执行,否则上层对象识别后则不再继续传播
//一句话总结就是此方法返回YES时,手势事件会一直往下传递,不论当前层次是否对该事件进行响应。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

if ([self panBack:gestureRecognizer]) {
return YES;
}
return NO;

}

//location_X可自己定义,其代表的是滑动返回距左边的有效长度
- (BOOL)panBack:(UIGestureRecognizer *)gestureRecognizer {

//是滑动返回距左边的有效长度
int location_X =0.15*IPHONE_W;

if (gestureRecognizer ==self.panGestureRecognizer) {
UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
CGPoint point = [pan translationInView:self];
UIGestureRecognizerState state = gestureRecognizer.state;
if (UIGestureRecognizerStateBegan == state ||UIGestureRecognizerStatePossible == state) {
CGPoint location = [gestureRecognizer locationInView:self];

//这是允许每张图片都可实现滑动返回
int temp1 = location.x;
int temp2 =IPHONE_W;
NSInteger XX = temp1 % temp2;
if (point.x >0 && XX < location_X) {
return YES;
}
}
}
return NO;

}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {

if ([self panBack:gestureRecognizer]) {
return NO;
}
return YES;

}

获取系统的UIPanGestureRecognizer的
(3) 侧滑手势优先,侧滑手势失效时,才触发UISrcollView的滑动

https://www.jianshu.com/p/8170fea174da

文章目录
  1. 1. 中间层的路由跳转方案
  2. 2. 整体导航条Navigation
  3. 3. 网络层
  4. 4. tableView自适应
    1. 4.1. 方法一
    2. 4.2. 方法二
    3. 4.3. 方法三
    4. 4.4. 方法四
    5. 4.5. 方法五
  5. 5. 整体的方法
  6. 6. 登录模块
  7. 7. 图片处理
  8. 8. 弹框处理
  9. 9. 时间处理
  10. 10. 下拉刷新和上拉加载更多
  11. 11. 第三方登录和第三方分享
  12. 12. 系统问题
  13. 13. 打包问题
  14. 14. 优化
    1. 14.0.1. 减少cellForRowAtIndexPath代理中的计算量
    2. 14.0.2. 减少heightForRowAtIndexPath代理中的计算量
  • 15. 数据刷新
    1. 15.1. tableView的数据刷新
  • 16. 把模块拆分成Pod
  • 17. 其他问题
    1. 17.1. UIScrollView的左右滑动与侧滑返回并存
  • 本站总访问量 本站访客数人次 ,