MobileOA第一期总结

   前段时间一直没有更新博客,好想给自己找个借口———恩,我还是多找几个吧。毕业论文、毕业照,再感伤一下,出去玩一下,不知不觉就过去几个月了。然后上个月底才重新回到学习之路,从此让我走上正轨吧。
这算是本宝宝人生中的第一个项目了,虽然分给我的两个模块都很基础,但在编写过程中,仍然出现很多问题。从编码习惯到后期的数据处理,总结一下,以后谨记。

一、问题

1、注释

这次项目过后,我才真正切身感受到注释的重要性———这次的项目有些大,一个师姐带着我编写。注释没写好,会让跟你合作的人平添各种麻烦,就连本人,到了后期,UI界面调整之后,又回过头找当初的初衷是在干嘛,浪费时间。

2、工作流逻辑

这次的OA项目,我一共写过三个模块——请假工作流,任务模块,会议模块

由于最初写的请假工作流,并没有什么太大的逻辑问题,与其他模块没有太大的关联,我只拘泥在自己的小世界里写自己的东西,结束后集成进去便无大碍。以至于,我在接到任务和工作流模块之后,也只是安心做自己的,到后来发现,这中间涉及到的方方面面,竟然与其他模块有着千丝万缕的联系,我从一开始的工作流走向与数据来源都没弄清楚,以至于在后面调接口的时候,牵扯进很多问题,甚至连UI都改了不少。

PS:可能是因为我们实验室没有专门的UI设计师,,,但至少,在以后两年的时间里,我懂得了,不要全信设计师,被坑得到最后都满脸懵逼。

3、数据渲染

由于这是第一次参与一个完整的项目,一开始便只顾着写死数据,把页面重现以为就OK了,却没有想到零零散散的数据会给后期的数据处理造成多大的麻烦,傻乎乎的甚至有些需要从后台获取的数据不知道在@interface里面声明。

4、接口调试

我的时间,大部分还是浪费在了调接口上,可能是因为我从一开始就对接口有一种莫名的恐惧感。一遇到问题,就开始怀疑自己的能力。

其次,在接口调试过程中,要学会调试,单步跟踪,清楚代码的走向,数据获取在哪一步出现了问题,到底是自己的参数问题还是后台接口的问题,不到万不得已也别怀疑接口,宝宝在被打脸n次后吸取了教训,再也不敢随便找接口的麻烦了。还好是在学校,这要是到了公司,估计再也没人愿意写我的接口了 - -

5、数据处理

刚刚开始的时候,我总是在子进程中处理数据,只拿出自己需要的字段。然而,UI只要出现一些小的变动,就得重新分析获取数据,徒增各种麻烦。

二、可重用代码

 以下是我在编写过程中用到的师姐的代码,先备份一下,有时间看看。

1、后台获取数据接口

(1)可刷新(分页)

- (void)setupRefresh { self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(headerRereshing)]; [self.tableView.mj_header beginRefreshing]; self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(footerRereshing)]; } #pragma mark 开始进入刷新状态 - (void)headerRereshing { [self loadTaskList:YES]; } - (void)footerRereshing { [self loadTaskList:NO]; } #pragma mark -- 获取任务数据 - (void)loadTaskList:(BOOL)isReFresh{ if (isReFresh) { _pageNum = 1; } NSString *urlStr = [NSString stringWithFormat:@"%@%@",BASE_URL,TaskList_URL]; NSDictionary *jsonParam = @{ @"telephone" : [NSUserDefaults getUserTelephone ], @"page" : @(_pageNum), @"pageSize" : @(10) }; [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; dispatch_queue_t myQueue = dispatch_queue_create([@"loadTaskList" UTF8String], NULL); dispatch_async(myQueue, ^{ //请求数据 NSData *data = [WebGetDataUtil getDataByURL:[NSURL URLWithString:urlStr ] withJsonParam:jsonParam]; NSError *error; if (data) { NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error ]; NSInteger code = [[dic objectForKey:@"code"]integerValue]; if (code == 1) { //判断服务器是否返回数据 NSError *error; NSArray *array = [dic objectForKey:@"data"]; if(array){ //判断返回的数据是否正确解析 dispatch_async(dispatch_get_main_queue(), ^{ //前台更新ui [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; NSDictionary * news = nil; NSDictionary * news1 = nil; if (self.taskData.count >0 && array.count >0) { news = [self.taskData objectAtIndex:(self.taskData.count - 1)]; news1 = [array objectAtIndex:array.count-1]; } if (array.count != 0 ) { BOOL addFlag = YES; if (news && !isReFresh) { //上拉加载的是后台给出的是重复数据 if ([news[@"id"]integerValue] == [news1[@"id"]integerValue]) { addFlag = NO; [KSToastView ks_showToast:@"已经是最后一条" duration:3.0f]; } } if (isReFresh) { [self.taskData removeAllObjects]; } if (addFlag) { [self.taskData addObjectsFromArray:array]; } [_tableView reloadData]; _pageNum ++; }else{ //没有新的数据 if(!isReFresh){ [KSToastView ks_showToast:@"已经是最后一条" duration:3.0f]; } } if(isReFresh) { [self.tableView.mj_header endRefreshing]; } else { [self.tableView.mj_footer endRefreshing]; } }); } else{ //数据解析有误 dispatch_async(dispatch_get_main_queue(), ^{ [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; NSLog(@"error:%@",error); if(isReFresh) [self.tableView.mj_header endRefreshing ]; else [self.tableView.mj_footer endRefreshing ]; }); } }else { dispatch_async(dispatch_get_main_queue(), ^{ [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; NSLog(@"error:%@",error); if(isReFresh) [self.tableView.mj_header endRefreshing ]; else [self.tableView.mj_footer endRefreshing ]; }); } } else{ //网络问题 dispatch_async(dispatch_get_main_queue(), ^{ [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; [KSToastView ks_showToast:@"无法连接网络,请检查网络设置" duration:3.0f]; if(isReFresh){ //加载本地条目 [self.tableView.mj_header endRefreshing]; } else [self.tableView.mj_footer endRefreshing ]; }); }}); }
(2)不可刷新
#pragma mark -- 获取后台数据
// 获取任务信息
- (void)getDetailTaskInfo {
NSString *urlStr = [NSString stringWithFormat:@"%@%@",BASE_URL, TaskDetailInfo_URL];
NSDictionary *jsonParam = @{ @"id" : @(self.taskId)};
NSLog(@"--%zd:",self.taskId);
NSLog(@"urlStr:%@",urlStr); dispatch_queue_t queue = dispatch_queue_create([@"getDetailTaskInfo" UTF8String], NULL);
dispatch_async(queue, ^{
NSData *data = [WebGetDataUtil getDataByURL:[NSURL URLWithString:urlStr ] withJsonParam:jsonParam];
if(data){
NSError *error;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
// NSLog(@"loginDic = %@", dic);
if (dic) {
NSInteger code = [[dic objectForKey:@"code"]integerValue];
dispatch_async(dispatch_get_main_queue(), ^{
if (code == 1) {
NSDictionary *task = [dic objectForKey:@"data"];
self.taskData = task;
[self updateViewData:task];
[self setView];
}else {
[KSToastView ks_showToast:[dic objectForKey:@"msg"] duration:3.0f];
}
}); }
}else{
dispatch_async(dispatch_get_main_queue(), ^{
[KSToastView ks_showToast:@"网络连接失败" duration:3.0f];
});
}
}); }

2、viewPager

(1)MyViewPageer.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> @class MyViewPager; //@protocol MyViewPagerDelegate <NSObject>
//
//- (void)myViewPager:(MyViewPager *)viewPager controllerViews:(NSArray *)controllerArray;
//
//@end @interface MyViewPager : UIView @property (nonatomic) NSInteger selectedView; + (instancetype)viewPagerWithFrame:(CGRect)frame controllersCount:(NSArray *)controllersArray textGroup:(NSArray *)textArray; @end
(2) MyViewPager.m
#import "MyViewPager.h"
#import "Constants.h" @interface MyViewPager () <UIScrollViewDelegate, UIGestureRecognizerDelegate> @property (nonatomic, strong) UIScrollView * scrollView;
@property (nonatomic, strong) NSMutableArray * controllerViews;
@property (nonatomic, strong) NSMutableArray * labelArray;
@property (nonatomic, strong) NSMutableArray * labelTextArray;
@property (nonatomic, strong) UIView * signalView;
@property (nonatomic, strong) NSMutableArray * flagArray;
@property (nonatomic) NSInteger pageNum; @end @implementation MyViewPager #define PAGE_COUNT 2
#define LABEL_HEIGHT 38
#define SIGNAL_VIEW_HEIGHT 2
//#define MINUS_HEIGHT (80 + Extra_Height*IS_iOS_7)
#define MINUS_HEIGHT 40 #define WIDTH self.frame.size.width
#define HEIGHT self.frame.size.height - (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self initialization];
}
return self;
} - (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
[self initialization];
}
return self;
} - (void)initialization{ _selectedView = 0;
_signalView = [[UIView alloc]init];
_signalView.backgroundColor = GLOBAL_COLOR;
_labelArray = [NSMutableArray arrayWithCapacity:0 ];
_flagArray = [NSMutableArray arrayWithCapacity:0 ]; } + (instancetype)viewPagerWithFrame:(CGRect)frame controllersCount:(NSArray *)controllersArray textGroup:(NSArray *)textArray{ CGFloat width = frame.size.width;
CGFloat height = frame.size.height; MyViewPager *viewPager = [[self alloc]initWithFrame:frame];
viewPager.pageNum = controllersArray.count;
viewPager.controllerViews = [NSMutableArray arrayWithArray:controllersArray ]; viewPager.scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, MINUS_HEIGHT, width, height - MINUS_HEIGHT)];
viewPager.scrollView.contentSize = CGSizeMake(width * viewPager.pageNum, height - MINUS_HEIGHT);
viewPager.scrollView.pagingEnabled = YES;
viewPager.scrollView.delegate = viewPager;
[viewPager addSubview:viewPager.scrollView];
[viewPager.scrollView addSubview: [controllersArray objectAtIndex: 0]]; viewPager.labelTextArray = [NSMutableArray arrayWithArray:textArray ];
UIView * backView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, width, MINUS_HEIGHT)];
backView.backgroundColor = [UIColor colorWithRed:250/255.0 green:250/255.0 blue:250/255.0 alpha:1 ];
[viewPager addSubview:backView]; CGFloat div_width = width/viewPager.pageNum;
for (int i = 0; i < viewPager.pageNum; i++) { [viewPager.flagArray addObject:@"0"]; UILabel * label = [[UILabel alloc ]initWithFrame:CGRectMake(i*div_width, 0, div_width, LABEL_HEIGHT)];
label.text = [textArray objectAtIndex:i];
label.textColor = [UIColor lightGrayColor ];
label.textAlignment = NSTextAlignmentCenter;
label.backgroundColor = [UIColor whiteColor ];//[UIColor colorWithRed:250/255.0 green:250/255.0 blue:250/255.0 alpha:1 ];
label.userInteractionEnabled = YES;
[backView addSubview:label]; label.tag = i + 301;
[viewPager addTapGesture:label]; if (i == 0) {
[viewPager.flagArray replaceObjectAtIndex:0 withObject:@"1"];
CGRect rect = CGRectMake(i*div_width, MINUS_HEIGHT - SIGNAL_VIEW_HEIGHT, div_width, SIGNAL_VIEW_HEIGHT);
viewPager.signalView.frame = rect;
[backView addSubview:viewPager.signalView ];
label.textColor = GLOBAL_COLOR;
}
[viewPager.labelArray addObject:label]; } return viewPager; } - (void)addTapGesture:(UILabel *) label{
UITapGestureRecognizer * singlTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
singlTap.delegate = self;
[label addGestureRecognizer:singlTap ]; } - (void)tap:(UIGestureRecognizer *)gestureRecognizer{
UILabel * label = (UILabel *)gestureRecognizer.view;
NSInteger tag = label.tag - 301;
CGFloat width = self.frame.size.width;
CGFloat div_width = width/self.pageNum;
CGFloat originX = tag*div_width;
if ([[self.flagArray objectAtIndex:tag] isEqualToString:@"0"]) {
[self.scrollView addSubview:[self.controllerViews objectAtIndex:tag]];
[self.flagArray replaceObjectAtIndex:tag withObject:@"1"];
}
//动画
[UIView transitionWithView:self
duration:0.3
options:UIViewAnimationOptionCurveEaseIn
animations:^{ UILabel *lastSelectedLabel = (UILabel *)[_labelArray objectAtIndex:_selectedView];
lastSelectedLabel.textColor = [UIColor lightGrayColor];
label.textColor = GLOBAL_COLOR;
_selectedView = tag;
_signalView.frame = CGRectMake(originX, MINUS_HEIGHT - SIGNAL_VIEW_HEIGHT, div_width, SIGNAL_VIEW_HEIGHT); } completion:nil]; [_scrollView scrollRectToVisible:CGRectMake(tag*width, MINUS_HEIGHT, self.frame.size.width, self.frame.size.height - MINUS_HEIGHT) animated:YES];
} //滑动结束
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ CGFloat width = self.frame.size.width;
CGFloat div_width = width/self.pageNum; CGPoint offset = scrollView.contentOffset; NSInteger currentPage = floor(offset.x/_scrollView.frame.size.width); if ([[self.flagArray objectAtIndex:currentPage ] isEqualToString:@"0"]) {
[self.scrollView addSubview:[self.controllerViews objectAtIndex:currentPage]];
[self.flagArray replaceObjectAtIndex:currentPage withObject:@"1"];
} for (int i = 0; i < _pageNum; i++) {
UILabel * label = (UILabel *)[_labelArray objectAtIndex:i ];
if (i == currentPage) {
label.textColor = GLOBAL_COLOR;
_signalView.frame = CGRectMake(i*div_width, MINUS_HEIGHT - SIGNAL_VIEW_HEIGHT, div_width, SIGNAL_VIEW_HEIGHT);
}else {
label.textColor = [UIColor lightGrayColor ];
}
} } @end

最新文章

  1. openfire中mysql的前期设置
  2. OPC客户端的进程安全初始化
  3. Silverlight开发工具汇总
  4. HDU 4455(dp)
  5. 201521123050《Java程序设计》第1周学习总结
  6. word设置每页50行
  7. Eclipse目录实解
  8. SQL Server 获取 ActiveDirectory 用户信息
  9. 各大型网站架构分析收集-原网址http://blog.csdn.net/lovingprince/article/details/3379710
  10. 4.json解析
  11. windows 环境下 ping 加时间戳 记日志
  12. VLC媒体视频播放器 v3.0.2官方版
  13. J03-Java IO流总结三 《 FileInputStream和FileOutputStream 》
  14. rmdir 命令(转)
  15. Android中Invalidate与postInvalidate的区别&lt;转&gt;
  16. .NET连接Oracle的方法
  17. 【Java】 奇偶数的判断
  18. 编写高质量代码改善C#程序的157个建议——建议109:谨慎使用嵌套类
  19. MVC返回数据流,ajax接受并保存文件
  20. Rabbitmq的五种模式和案例

热门文章

  1. xamarin mac 基础知识 之 界面
  2. Python - Headless Selenium WebDriver Tests using PyVirtualDisplay
  3. vdi、vhd、vmdk虚拟格式转换
  4. Javascript正则表达式完全学习手册
  5. 邮件报警shell脚本
  6. 微信小程序来了,小程序都能做些什么
  7. 关于js中for in的缺陷浅析
  8. jquery图片放大镜和遮罩层效果
  9. Flash Socket通信的安全策略问题 843端口
  10. Mysql密码忘记后如何重设密码