基于iOS的简单计算器(一)

郑天寿
• 阅读 15362

这个与上一篇的表达式求值都是iOS课程实验内容,老师演示了一个用NSExpression实现的版本,让我们用表达式求值的方式实现==

使用NSExpression实现

NSExpression是什么

基础的教程里并没有介绍这个,网上有关的中文介绍也比较少,有一篇NSHipster的文章,不过看完还是不怎么了解NSExpression,所以这块等稍后研究下官方文档后再补充。

思路

还是用MVC的模型.

  • 先"画"出计算器的样子,一个比较简单的计算器,可以进行四则运算。

  • Model里面主要实现下面三个方法:

        -(void)delNumber;//退格
        -(NSString *)compute;//计算
        -(void)clearSpace;//清空输入
    
  • 最后,ViewController需要做的是,将用户键入的字符“拼装”成字符串,然后交给Model去处理。

需要注意的地方

  • 初始化calculator的实例对象
    在viewDidLoad中,视图控制器初始化的时候要确保生成calculator(Model)的实例对象:

       self.calculator = [[Calculator alloc]init];
    
  • 覆盖calculator的getter方法
    保证每次都能得到一个对象,而不是一个空指针

    • (Calculator *)calculator

        {
            if (!_calculator) {
                _calculator = [[Calculator alloc]init];
            }
            return _calculator;
        }
      
  • 处理特殊字符
    乘除按钮是用的特殊字符输入的,要进行计算的话需要转换成 * / 符号。

实现圆角

给按钮添加一点角度就可以变成圆角,关键是将这段修改的代码放在哪里?

  • 利用viewWillAppear
    在视图显示的时候

  • 利用awakeFromNib
    新建一个类btnView,继承自UIButton,所以它可以覆盖awakeFromNib的方法。

每一次,按钮被唤醒的时候,都会被调用。将按钮的class改成btnView即可。

使用数值表达式实现

思路

可以直接利用之前的数值表达式的Model,所以要做的就剩两件事:一个是“画”计算器的界面,另一个就是“拼装”输入的字符串。

遇到的问题

在字符串末尾添加等号

由于我的Model设计的时候,要在表达式的末尾输入"="才能计算输出结果,所以在用户按下"="的时候,在将输入字符串input送入Model的ExpressionCalculate方法计算之前,在其末尾添加一个"="即可,这个"="可以直接从button的titleLabel获得。

NSMutableString *computeStr = [NSMutableString stringWithString:self.calculator.input];
[computeStr appendString:[[sender titleLabel] text]];

连续计算

最开始会发生连续计算失败的情况,比如,先输入10*10+20,计算得到120,如果再接着按下+10=x2即我想计算(120+10)x2计算结果是140而非260。
原因是textfield中的字符串虽然变了,但是calculator类中的input没有变,比如上面的式子,连续计算的话,input = 10x10+20+10x2 这样一个字符串。
修改的话就在每次计算完成后,将input的值改得跟textfiled里的值一样就可以了。

两次退格?

这是直接copy老师代码的后果==
在delNumber方法里面,将textfield里的字符删掉一个之后,又让input也调用了delNumber方法,而我每次计算之后又将input的值改得跟textfiled一样了,所以相当于退格了两次。
修改的话input不要再调用delNumber方法就可以了。

其它

  • 特殊字符
    减号上的'-'是通过插入特殊字符里的数学符号插入的,进行isEqualToString:的时候就不是运算用的'-'了,把它删了直接从键盘输入。

不过用NSExpression的话,不用改也没问题(这里也显示出NSExpression真心强大

待改进

非法输入的检查√

原来数值表达式模型中的输入检查会将"."也误判为非法运算符,我得再改改==
原来数值表达式中只考虑输入如英文字符等非法字符情况,由于在计算器中只允许输入数字和运算符,所以不合法的情况应该是输入连续的运算符,已有的方法isOperator可以用来判断,但要注意括号和其它运算符可以连续出现。

整数也有好多小数点√

为了够算定义的double类型,但是这样每次结果都带了好多0,小数就算了,整数结果也是这样,看着好心塞……
添加了判断是否为整数的方法,虽然很简单粗暴,but it works:将doubleValue和intValue相减,如果为0则为整数,否则就是浮点数==
希望好心人提供更好的idea。

效果图

基于iOS的简单计算器(一)

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Karen110 Karen110
4年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
4年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
4年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
郑天寿
郑天寿
Lv1
想要飞行,想要落在屋顶。
文章
3
粉丝
0
获赞
0