2.之前看了很多demo,第一次来完全的自己实现一个APP
3.完成之后提交AppStore
4.作为GoodCoder的提交审核材料
二、排期
7.18-7.19:完成MRD设计
7.20-7.24:完成技术框架搭建,包括:MVC、基类设计和功能分工、Pod库的选取
7.25-8.9:完成全功能第一版
8.10-8.16:整理优化
三、MRD
7.20
第一步模仿AppStore的房贷计算器设计UI(工具:keynote)
第二步增加新的功能
1.提前还款功能
2.央行降息后还款金额变化
3.公积金贷款额度查询
4.点击非编辑区域,收起键盘
四、技术框架
1.工程名:HouseLoanCal,所有类前缀:HLC
2.Controller底部是UITabBarController公积金贷款:HLCProvidentFundLoanController商业贷款:HLCCommercialLoanController混合贷款:HLCMixedLoanController继承自HLCLoanController,继承HLCTableViewController,继承自UITableViewController
3.View基本上靠TableView可以实现,不需要专门的View
4.Model首先,三种贷款模式(公积金贷款、商业贷款、混合贷款),都可以归结为一,即贷款金额+贷款利率公积金贷款:贷款金额=贷款金额贷款利率=贷款利率商业贷款:贷款金额=贷款金额贷款利率=贷款利率*折扣组合贷款:贷款金额=公积金贷款金额+商业贷款金额贷款利率=(公积金贷款金额*公积金贷款利率+商业贷款金额*商业贷款利率*折扣)/(公积金贷款金额+商业贷款金额)
输入数据贷款金额:单位为万元,其他金额数字基本为元贷款利率:默认值为当前利率(目前暂时未找到免费的利率接口,先写在本地)贷款期限:必须为>0整数还款日期:存的是年月日,显示的是年月,默认值为当前日期还款方式:枚举类型,决定了计算的结果
输出数据折合利率:累计支付利息:累计还款总额:
每期还款、每期本金、每期利息当为等额本息时,头部显示每期还款,下面列表显示本金/利息当为等额本金时,头部显示每期本金,下面列表显示还款/利息下面的列表行数=贷款期限*12
五、实现中遇到的问题和解决方案
7.21
问题1
controller的框架搭建起来,运行了一次发现navigationItem的title未显示,排查发现controller的viewDidLoad没有运行进去
解决方法
HLCBaseTableViewController继承了UITableViewController,它本来就有一个属性tableView
self.tableView的操作移到viewDidLoad即可
7.27
问题2
自定义的cell,点击之后,分割线会消失
7.29
问题3
之前是Setting页面定义了多个cell,打算整合成一个,用cellstyle来区分,类似UITableViewCellStyle
8.17
等额本息计算公式:
每月本息=贷款本金*{月利率*[(1+月利率)^还款月数]}/{[(1+月利率)^还款月数]-1}
等额本金计算公式:
每月本息=(贷款本金/还款月数)+(本金-已归还本金累计额)*每月利率
8.24
NSNumber转NSString
最初的做法如下,缺点是显示的金额会带一个$符号
NSNumberFormatter*numFormatter=[[NSNumberFormatteralloc]init];numFormatter.numberStyle=NSNumberFormatterCurrencyStyle;str=[numFormatterstringFromNumber:num];解决方法
NSNumberFormatter*moneyFormatter=[[NSNumberFormatteralloc]init];[moneyFormattersetPositiveFormat:@"###,##0.00"];str=[moneyFormatterstringFromNumber:num];
8.25
实现了公积金贷款页的输入、输出,但是发现,上滑后滑回,每一期列表数据会错乱,怀疑跟复用同一个cellIdentifier有关,排查一下
错误代码如下:
staticNSString*cellIdentifier=@"OutputDetailCellIdentifier";HLCLoanOutputTableViewCell*cell=[tableViewdequeueReusableCellWithIdentifier:cellIdentifier];if(!cell){cell=[[HLCLoanOutputTableViewCellalloc]initWithHLCStyle:HLCLoanOutputTableViewCellStyleSmallreuseIdentifier:cellIdentifier];[cellsetTitle:[NSStringstringWithFormat:@"第%ld期",row-1]];NSString*everyMonthDiffString=[moneyFormatterstringFromNumber:self.everyMonthDiff[row-2]];NSString*evertMonthInterestString=[moneyFormatterstringFromNumber:self.everyMonthInterest[row-2]];[cellsetDetail:[NSStringstringWithFormat:@"%@/%@",everyMonthDiffString,evertMonthInterestString]];}returncell;正确做法如下:
staticNSString*cellIdentifier=@"OutputDetailCellIdentifier";HLCLoanOutputTableViewCell*cell=[tableViewdequeueReusableCellWithIdentifier:cellIdentifier];if(!cell){cell=[[HLCLoanOutputTableViewCellalloc]initWithHLCStyle:HLCLoanOutputTableViewCellStyleSmallreuseIdentifier:cellIdentifier];}[cellsetTitle:[NSStringstringWithFormat:@"第%ld期",row-1]];NSString*everyMonthDiffString=[moneyFormatterstringFromNumber:self.everyMonthDiff[row-2]];NSString*evertMonthInterestString=[moneyFormatterstringFromNumber:self.everyMonthInterest[row-2]];[cellsetDetail:[NSStringstringWithFormat:@"%@/%@",everyMonthDiffString,evertMonthInterestString]];returncell;每次去调用tableView:cellForRowAtIndexPath:首先会调用dequeueReusableCellWithIdentifier判断cell池中是否有可重用的cellIdentifier,若有则直接用,若没有则重新init一个
这次出的问题在于,对于cell上面的textLabel操作,错放在了if(!cell){//...}里面,导致若有可重用的,会直接返回cell,而不会对textLabel处理
解决方法就是把对cell的处理挪到if判断的外面
公积金贷款页基本功能已经实现,梳理一下存在的问题:
1.计算结果有误差(100万30年5.0等额本息,累计利息有1.36元误差)
等额本金是准的,应该是等额本息的计算方法中精度问题引入了误差;
发现是AppStore的房贷计算器计算有误差,我的计算方法和精度是ok的
done
2.贷款利率需要设定默认值
NSCalendar*calendar=[[NSCalendaralloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];NSDateComponents*dateComponents=[[NSDateComponentsalloc]init];[dateComponentssetMonth:i];NSDate*monthDate=[calendardateByAddingComponents:dateComponentstoDate:self.loanDateoptions:0];done
5.tableViewCell无上分割线
解决方法是viewForHeaderInSection里面加一个下分割线
6.输入为空点击计算会Crash
7.重置功能
8.完成商业贷款、组合贷款两个页面
9.在iPhone6/6p上的尺寸适配问题
10.上滑时,header不要吸顶
解决方法一:
-(void)scrollViewDidScroll:(UIScrollView*)scrollView{if(scrollView.contentOffset.y<=kHLCHeightForCellHeader&&scrollView.contentOffset.y>=0){scrollView.contentInset=UIEdgeInsetsMake(-scrollView.contentOffset.y,0,0,0);}elseif(scrollView.contentOffset.y>=kHLCHeightForCellHeader){scrollView.contentInset=UIEdgeInsetsMake(-kHLCHeightForCellHeader,0,0,0);}}发现吸顶的问题是解决了,但是下滑后再上滑回来,顶部会部分被navigationBar遮挡
解决方法二:
分割区域不用header实现,而是每个section底部加一个cell
11.好评跳转功能
"_sqlite3_prepare_v2",referencedfrom:
_execute_prepared_config_stmtinlibWeChatSDK.a(MTAWXOStore.o)_execute_prepared_events_stmtinlibWeChatSDK.a(MTAWXOStore.o)
解决方法:
在LinkBinaryWithLibraries中依次加入libsqlite3.dylib,libz.dylib,libc++.dylib添加后就可以编译通过
(注意:Xcode7之后,.dylib库需要换成同名的.tbd)
iOS9之后,schema跳转需要在Info.plist中加一个LSApplicationQueriesSchemes的数组值
微博SDK接入(注意iOS9有更新,需要下2015.9.29最新的sdk)
Undefinedsymbolsforarchitecturearm64:"_OBJC_CLASS_$_CTTelephonyNetworkInfo",referencedfrom:objc-class-refinlibWeiboSDK.a(WBSDKPhoneCountryView.o)ld:symbol(s)notfoundforarchitecturearm64clang:error:linkercommandfailedwithexitcode1(use-vtoseeinvocation)
TARGETS-BuildPhases-LinkBinaryWithLibraries
加上CoreTelephony.framework
-[NSConcreteMutableDatawbsdk_base64EncodedString]:unrecognizedselectorsenttoinstance0x14758e840
Target->BuidSettings->Linking下OtherLinkerFlags项添加-ObjC
打开了微博客户端,提示“ssopackageorsignerror”
需要在友盟后台绑定第三方账号
13.给每个Item做个图标
初步想法是,一个圈分别加上公、商、组三个字,设置的就保留螺丝的图标
最终用sketch绘制
代码如下
1UIImage*tabImage=[UIImageimageNamed:@"icon_profund_normal"];2UIImage*tabSelectImage=[UIImageimageNamed:@"icon_profund_height"];3tabSelectImage=[tabSelectImageimageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];4self.tabBarItem=[[UITabBarItemalloc]initWithTitle:@"公积金"image:tabImageselectedImage:tabSelectImage];注意:要加上第3行,表示选中时的图标保持原样,不做渲染
如果不写上这句,图片做渲染之后,就会变成实心的
14.Applcon
Sketch绘制
整体布局与系统的计算器类似,房子和人命币图案寓意房子和贷款,加减符号寓意计算器
配色上,橘色和蓝色取得是IEEE官网的配色,比较喜欢
这个icon想了一晚上,最终比较满意
15.app名字
极简房贷计算器
这个需要个server,先看看有没有现成的,不行的话看看用python写一个
17.支持夜间模式
配色可以考虑参考NStats
18.版本号自动配置
//版本号#defineHLC_APP_VERSION([[[NSBundlemainBundle]infoDictionary]objectForKey:@"CFBundleShortVersionString"])//使用[cellsetTitle:@"当前版本"];[cellsetContent:[NSStringstringWithFormat:@"%@",HLC_APP_VERSION]];配置的位置
TARGET选择项目-General-Identity-Version
填1.0.0
另外下面的Build可以填1.0.0.0
19.下滑支持把键盘收起
加一句即可
self.tableView.keyboardDismissMode=UIScrollViewKeyboardDismissModeInteractive;
20.贷款期限用自定义Picker来实现
修改过程中,出现:EXC_BAD_ACCESS(code=EXC_I386_GPFLT)
这是请求了空指针
查到原因:
//贷款期限@property(nonatomic,assignstrong)NSNumber*loanPeriod;这个类型,之前是NSInteger,后来为了兼容小数而改成NSNumber,但是忘了更改类型,导致出血空指针
21.数组叠加bug
复现步骤:先选择30年,计算一次,结果是360期;再选择20年,计算一次,理论应该是240期,但现在是600期
//计算前清空之前的结果[self.eachInterestremoveAllObjects];[self.eachMonthremoveAllObjects];[self.eachPrincipalremoveAllObjects];[self.eachPrincipalPlusInterestremoveAllObjects];[self.eachDiffremoveAllObjects];这种NSMutableArray类型,每次计算前,需要清空
2015.10.9
1.0.0版本已上架
友盟统计
Bug1:
DeploymentTarget误选成8.4导致只能是8.4版本即以上才能下载,下个版本修复
Bug2:
在6和6p上没有做好屏幕适配,只是单纯的放大版
2015.10.27
提交GoodCooder,被驳回,原因一是代码逻辑太简单,二是没用单测(本想用UITesting代替单测,被说这是可以录制的,不可)