• ★房贷计算器 APP


    一、目的

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

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

    3. 完成之后提交 App Store 

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

      

    二、排期

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

    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-1]];
        NSString *everyMonthDiffString = [moneyFormatter stringFromNumber:self.everyMonthDiff[row-2]];
        NSString *evertMonthInterestString = [moneyFormatter stringFromNumber:self.everyMonthInterest[row-2]];
        [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-1]];
    NSString *everyMonthDiffString = [moneyFormatter stringFromNumber:self.everyMonthDiff[row-2]];
    NSString *evertMonthInterestString = [moneyFormatter stringFromNumber:self.everyMonthInterest[row-2]];
    [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. 利率更新提示(更新当天);

     

     

     

  • 相关阅读:
    angular 写 文字省略显示指令
    REACT 学习之一:普通表单过滤
    怎么能够做到实时的邮件监听-- 求指点
    C++实现Behavioral
    private virtual in c++
    接口污染
    C++ 虚函数&纯虚函数&抽象类&接口&虚基类(转)
    c++ override 关键字
    virtual function c++
    删完垃圾代码2
  • 原文地址:https://www.cnblogs.com/mobilefeng/p/4654819.html
Copyright © 2020-2023  润新知