一、目的

1. 这是一个蛮有用的小工具

2. 之前看了很多demo,第一次来完全的自己实现一个APP

3. 完成之后提交 App Store

4. 作为Good Coder的提交审核材料

二、排期

周日 周一 周二 周三 周四 周五 周六
            18
19 20 21 22 23 24 25
26 27 28 29 30 31
3 4 5 6 7
10 11 12 13 14
           

7.18-7.19:完成MRD设计

7.20-7.24:完成技术框架搭建,包括:MVC、基类设计和功能分工、Pod库的选取

7.25-8.9:完成全功能第一版

8.10-8.16:整理优化

三、MRD

7.20

第一步 模仿App Store的房贷计算器设计UI(工具:keynote)

第二步 增加新的功能

1. 提前还款功能

2. 央行降息后还款金额变化

3. 公积金贷款额度查询

4. 点击非编辑区域,收起键盘

四、技术框架

7.20

1. 工程名:HouseLoanCal,所有类前缀:HLC

2. Controller
底部是UITabBarController
公积金贷款:HLCProvidentFundLoanController
商业贷款:HLCCommercialLoanController
混合贷款:HLCMixedLoanController
继承自HLCLoanController,继承HLCTableViewController,继承自UITableViewController

3. View
基本上靠TableView可以实现,不需要专门的View

4. Model
首先,三种贷款模式(公积金贷款、商业贷款、混合贷款),都可以归结为一,即贷款金额+贷款利率
公积金贷款: 贷款金额=贷款金额 贷款利率=贷款利率
商业贷款: 贷款金额=贷款金额 贷款利率=贷款利率*折扣
组合贷款: 贷款金额=公积金贷款金额+商业贷款金额 贷款利率=(公积金贷款金额*公积金贷款利率+商业贷款金额*商业贷款利率*折扣)/(公积金贷款金额+商业贷款金额)

输入数据
贷款金额:单位为万元,其他金额数字基本为元
贷款利率:默认值为当前利率(目前暂时未找到免费的利率接口,先写在本地)
贷款期限:必须为>0整数
还款日期:存的是年月日,显示的是年月,默认值为当前日期
还款方式:枚举类型,决定了计算的结果

输出数据
折合利率:
累计支付利息:
累计还款总额:

每期还款、每期本金、每期利息
当为等额本息时,头部显示每期还款,下面列表显示本金/利息
当为等额本金时,头部显示每期本金,下面列表显示还款/利息
下面的列表行数=贷款期限*12

5. 设置里面
版本:写死
评分:跳转到App Store
推荐给朋友:调起分享SDK

五、实现中遇到的问题和解决方案

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 = [[NSNumberFormatter alloc] init];
numFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
str = [numFormatter stringFromNumber:num];

解决方法

NSNumberFormatter *moneyFormatter = [[NSNumberFormatter alloc] init];
[moneyFormatter setPositiveFormat:@"###,##0.00"];
str = [moneyFormatter stringFromNumber:num];

8.25

实现了公积金贷款页的输入、输出,但是发现,上滑后滑回,每一期列表数据会错乱,怀疑跟复用同一个cellIdentifier有关,排查一下

错误代码如下:

static NSString *cellIdentifier = @"OutputDetailCellIdentifier";
HLCLoanOutputTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[HLCLoanOutputTableViewCell alloc] initWithHLCStyle:HLCLoanOutputTableViewCellStyleSmall reuseIdentifier:cellIdentifier];
[cell setTitle:[NSString stringWithFormat:@"第%ld期", row-]];
NSString *everyMonthDiffString = [moneyFormatter stringFromNumber:self.everyMonthDiff[row-]];
NSString *evertMonthInterestString = [moneyFormatter stringFromNumber:self.everyMonthInterest[row-]];
[cell setDetail:[NSString stringWithFormat:@"%@/%@", everyMonthDiffString, evertMonthInterestString]];
}
return cell;

正确做法如下:

static NSString *cellIdentifier = @"OutputDetailCellIdentifier";
HLCLoanOutputTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[HLCLoanOutputTableViewCell alloc] initWithHLCStyle:HLCLoanOutputTableViewCellStyleSmall reuseIdentifier:cellIdentifier];
}
[cell setTitle:[NSString stringWithFormat:@"第%ld期", row-]];
NSString *everyMonthDiffString = [moneyFormatter stringFromNumber:self.everyMonthDiff[row-]];
NSString *evertMonthInterestString = [moneyFormatter stringFromNumber:self.everyMonthInterest[row-]];
[cell setDetail:[NSString stringWithFormat:@"%@/%@", everyMonthDiffString, evertMonthInterestString]];
return cell;

每次去调用 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. 贷款利率需要设定默认值

done

3. 重置后,贷款期限和贷款时间未被重置

4. 每一期加上时间

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setMonth:i];
NSDate *monthDate = [calendar dateByAddingComponents:dateComponents toDate:self.loanDate options:0];

done

5. tableViewCell无上分割线

解决方法是viewForHeaderInSection 里面 加一个下分割线

done

6. 输入为空点击计算会Crash

done

7. 重置功能

done

8. 完成商业贷款、组合贷款两个页面

done

9. 在iPhone 6/6p上的尺寸适配问题

done

10. 上滑时,header不要吸顶

解决方法一:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y <= kHLCHeightForCellHeader && scrollView.contentOffset.y >= 0) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y >= kHLCHeightForCellHeader) {
scrollView.contentInset = UIEdgeInsetsMake(-kHLCHeightForCellHeader, 0, 0, 0);
}
}

发现吸顶的问题是解决了,但是下滑后再上滑回来,顶部会部分被navigationBar遮挡

解决方法二:

分割区域不用header实现,而是每个section底部加一个cell

done

11. 好评跳转功能

done

12. 推荐给朋友的分享功能(微信好友、朋友圈、微博)

友盟(分享、统计SDK)

分享:

http://dev.umeng.com/social/ios/quick-integration

接入微信SDK时,会报一片

"_sqlite3_prepare_v2", referenced from:

_execute_prepared_config_stmt in libWeChatSDK.a(MTAWXOStore.o)
_execute_prepared_events_stmt in libWeChatSDK.a(MTAWXOStore.o)

解决方法:

在Link Binary With Libraries  中依次加入 libsqlite3.dylib ,libz.dylib, libc++.dylib添加后就可以编译通过

(注意:Xcode7之后,.dylib库需要换成同名的.tbd)

iOS9之后,schema跳转需要在Info.plist中加一个LSApplicationQueriesSchemes的数组值

分别加上 weixin, wechat, 微信 appid 三项

微信开发平台

https://open.weixin.qq.com

微博开放平台

http://open.weibo.com

QQ开放平台

http://open.qq.com

微博SDK接入(注意iOS9有更新,需要下2015.9.29最新的sdk)

问题1

Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_CTTelephonyNetworkInfo", referenced from:
objc-class-ref in libWeiboSDK.a(WBSDKPhoneCountryView.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

解决方法:

TARGETS-Build Phases-Link Binary With Libraries

加上 CoreTelephony.framework

问题2

-[NSConcreteMutableData wbsdk_base64EncodedString]: unrecognized selector sent to instance 0x14758e840

解决方法:

Target->Buid Settings->Linking 下 Other Linker Flags 项添加-ObjC

问题3

打开了微博客户端,提示“sso package or sign error”

解决方法:

http://dev.umeng.com/social/ios/operation#3

需要在友盟后台绑定第三方账号

绑定地址:http://umeng.com/apps

选择app-社会化分享-新浪微博填上 App Key 和 App Secret

done

13.  给每个Item做个图标

初步想法是,一个圈分别加上 公、商、组三个字,设置的就保留螺丝的图标

最终用sketch绘制

代码如下

1 UIImage *tabImage = [UIImage imageNamed:@"icon_profund_normal"];
2 UIImage *tabSelectImage = [UIImage imageNamed:@"icon_profund_height"];
3 tabSelectImage = [tabSelectImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
4 self.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"公积金" image:tabImage selectedImage:tabSelectImage];

注意:要加上第3行,表示选中时的图标保持原样,不做渲染

如果不写上这句,图片做渲染之后,就会变成实心的

done

14. App lcon

Sketch绘制

整体布局与系统的计算器类似,房子和人命币图案寓意房子和贷款,加减符号寓意计算器

配色上,橘色和蓝色取得是IEEE官网的配色,比较喜欢

这个icon想了一晚上,最终比较满意

done

15. app名字

极简房贷计算器

done

16. 实时获取当前时间的贷款利率

这个需要个server,先看看有没有现成的,不行的话看看用python写一个

17. 支持夜间模式

配色可以考虑参考 N Stats

18. 版本号自动配置

// 版本号
#define HLC_APP_VERSION ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]) // 使用
[cell setTitle:@"当前版本"];
[cell setContent:[NSString stringWithFormat:@"%@", HLC_APP_VERSION]];

配置的位置

TARGET 选择项目 - General - Identity - Version

填1.0.0

另外下面的 Build 可以填1.0.0.0

done

19. 下滑 支持把键盘收起

加一句即可

self.tableView.keyboardDismissMode  = UIScrollViewKeyboardDismissModeInteractive;

done

20. 贷款期限用自定义Picker来实现

修改过程中,出现:EXC_BAD_ACCESS(code=EXC_I386_GPFLT)

这是请求了空指针

查到原因:

// 贷款期限
@property (nonatomic, assign strong) NSNumber *loanPeriod;

这个类型,之前是NSInteger,后来为了兼容小数而改成NSNumber,但是忘了更改类型,导致出血空指针

done

21. 数组叠加bug

复现步骤:先选择30年,计算一次,结果是360期;再选择20年,计算一次,理论应该是240期,但现在是600期

解决方法:

// 计算前清空之前的结果
[self.eachInterest removeAllObjects];
[self.eachMonth removeAllObjects];
[self.eachPrincipal removeAllObjects];
[self.eachPrincipalPlusInterest removeAllObjects];
[self.eachDiff removeAllObjects];

这种NSMutableArray类型,每次计算前,需要清空

done

2015.10.9

1.0.0 版本已上架

http://itunes.apple.com/app/id1043888133

友盟统计

http://www.umeng.com/apps

Bug1:

Deployment Target 误选成8.4 导致只能是8.4版本即以上才能下载,下个版本修复

Bug2:

在6和6p上没有做好屏幕适配,只是单纯的放大版

2015.10.27

提交Good Cooder,被驳回,原因一是代码逻辑太简单,二是没用单测(本想用UI Testing代替单测,被说这是可以录制的,不可)

先不提交了,开始着手1.1.0版本改造

2015.10.28

1.1.0版本新增功能:

1. 实现实时更新最新利率,利率选择改成Picker形式,利率值与利率更新时间对应,同时也可以支持自定义输入,默认选中最新利率;

2. 折扣改成常见折扣Picker选择,也可支持自定义输入;

3. UI优化;

4. bug修复;

5. 利率更新提示(更新当天);

★房贷计算器 APP的更多相关文章

  1. Android实战项目:房贷计算器

    APP源码已上传到我的GitHub:https://github.com/zdm-code/Android-learning/tree/master/android_learning/mortgage ...

  2. JavaScript:综合案例---房贷计算器的实现

    房贷计算器的实现 (可以使用的编辑器:webStrom.subLime.notePad++.editPlus) 输入数据: 平方单价 70,000.00 元/平方  B1 租金 382.50 元/平方 ...

  3. C# 房贷计算器

    设计背景 百度小程序中的房贷计算器不能满足我个人的需求,故而开发一个.NET小程序.希望后期能用JS重写,发布在网上供大家使用. 设计思路 根据百度公式:等额本息月还款 = [贷款本金×月利率×(1+ ...

  4. 复利计算器app发布

    复利计算器app发布 抱歉:由于无法实现服务端的持续开启,发布的app仅为简单的单机版,暂时舍弃了c/s版本的一些功能,如:投资动态管理功能. 应用详情博客:请点击这里 apk下载地址1(百度手机助手 ...

  5. 纯js房贷计算器开源

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. PHP房贷计算器代码,等额本息,等额本金

    debx(); function debx() { $dkm = 240; //贷款月数,20年就是240个月 $dkTotal = 10000; //贷款总额 $dknl = 0.0515; //贷 ...

  7. IOS之计算器实现

    本文利用ios实现计算器app,后期将用mvc结构重构 import UIKit class CalculViewController: UIViewController { @IBOutlet we ...

  8. 哪些产品不用开发原生APP,微信公众号就够了?

    最近一阶段H5技术被推到高峰,很多人认为借助H5就能利用微信公众号取代APP原生应用了,而事实是怎么样的?这里我从产品层做一个客观分析. 一,原生APP总体趋势 要谈APP是否会被微信取代,那么必须回 ...

  9. 手游与App测试如何快速转型? —— 过来人科普手游与App测试四大区别

    随着智能设备的普及和移动互联网的兴起,各家互联网巨头纷纷在往移动端布局和转型,同时初创的移动互联网公司也都盯着这个市场希望分一杯羹.在这个大环境下,互联网的重心已经慢慢从Web端转向了移动端,而移动端 ...

随机推荐

  1. 解决overflow: auto在Ios中滑动不流畅

    [bug]—— H5页面在 ios 端滑动不流畅的问题   IOS系统的惯性滑动效果非常6,但是当我们对div加overflow-y:auto;后是不会出这个效果的,滑动的时候会感觉很生涩.怎么办? ...

  2. Codevs 3409 搬运礼物

    3409 搬运礼物 CodeVS原创  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 青铜 Bronze 题解       题目描述 Description 小浣熊松松特别喜欢交 ...

  3. Java 虚拟机(Java Virtual Machine)

    Java 编译器将 Java 程序编译成虚拟机能够识别的二进制代码,这种代码称为字节码(Bytecode).字节码就是虚拟机的机器指令,它与平台无关,有统一的格式,不依赖于具体的硬件环境,只运行在 J ...

  4. extern用法详解(转)

    1 基本解释 extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义. 另外,extern也可用来进行链接指定. 2 问题:ext ...

  5. Visual Studio 2015、2013、2012、2010、2008、2005各版本下载+有效密钥激活

    Visual Studio是微软发布的一个集成开发工具,业内一般简称为VS,广泛应用于Windows软件开发.网站开发等,是目前十分流行的windows应用程序的集成开发工具,如果大家不了解,可以简单 ...

  6. VLAN-3-VLAN Trunk:ISL和802.1Q

      (1)ISL和802.1Q概念       通过使用VLAN Trunk链路,设备可以通过一条链路发送去往多个vlan的流量.为了知道数据帧属于哪个vlan,发送方会添加原始以太网数据帧的头部,这 ...

  7. python 基础(十五) socket编程

    SOCKET TCP协议: 有请求 有响应 称之为 tcp协议 是面向连接的协议 就是在收发数据之前 必须先要建立一个可靠的链接 三次握手 如:网站 UDP协议: 是一个非链接的协议 传输之前不需要键 ...

  8. 转 open_cursors参数设置调优

    https://www.cnblogs.com/Peyton-for-2012/archive/2013/05/07/3065058.html

  9. [已读]高性能JavaScript

    值得多读几遍的书.

  10. var声明提前 undefined

    1.同一代码块内,所有var声明都提前: 2.var 变量的初始化不提前,按顺序执行: 3."undefined"和undefined都存在于window中: 4.if(" ...