Author 谭梓煊 (1853434)
[TOC]
使用UIKit和SwiftUI分别开发一个计算器应用程序。具体要求如下:
-
使用UIKit开发计算器
-
使用MVC架构进行计算器开发,代码中需要包括Model、View、Controller的部分
-
使用AutoLayout,使得计算器能够在不同的iPhone和iPad上正常显示
-
通过测试的设备(由小到大): iPod touch(7th), iPhone 8 SE, iPad(8th)
-
-
使用SwiftUI开发计算器
-
使用MVVM架构进行计算器开发
-
计算器能够在不同的iPhone和iPad上正常显示
-
通过测试的设备(由小到大): iPod touch(7th), iPhone 8 SE, iPad(8th)
-
-
奖励部分(选做)
-
计算器支持多步计算(需要支持运算符优先级、小括弧等)
-
支持的运算符: 加&正+, 减&负-, 乘*, 除/, 乘方^, 取模%, 开根号√
-
支持小括弧()
-
支持运算符优先级
-
计算器的核心逻辑位于Core.swift
文件中, 主要包括一个eval(_ : String) throws -> Double
函数, 用于求解一个字符串表达式. 两个版本的计算器的核心求解器完全一样.
eval
函数内部实现了经典的基于栈的表达式求解算法, 支持运算符优先级和小括号
使用了两个栈: 一个操作数栈opnd: [Double]
+ 一个操作符栈optr: [Optr]
-
while 运算符栈不空
-
每次从输入字符串中读取一个字符
-
如果是数字, 则调用
Scanner
类的scanDouble
方法解析一个数字, 读取指针后移 -
否则是运算符, 首先调用
dispatch
函数判断运算符类型, 某些多义运算符, 如减号和负号, 根据前一个字符的类型来区别-
判断运算符栈顶的运算符和当前运算符的优先级 (通过查表法)
-
如果当前运算符优先级较高: 将当前运算符压栈
-
如果栈顶运算符优先级较高: 从操作数栈中弹出一或两个操作数, 从运算符栈中弹出一个运算符, 进行运算后压回
-
否则: 从运算符栈中弹出一个运算符
-
-
-
则操作数栈所剩的数字为最终结果
为方便处理, 在算法开始时, 向运算符栈中和表达式末尾都添加一个=
.
程序定义了三种错误, 分别为算术错误、语法错误和输入错误.
-
算数错误包括除以0, 对0取模, 对负数开根号等;
-
语法错误表示输入表达式中运算符的顺序不正确等;
-
输入错误表示输入表达式中有未知字符.
enum CalcError: Error {
case ArithmeticError(detail: String)
case SyntaxError(detail: String)
case InputError(detail: String)
}
- UIKit 版的计算器 UI 完全使用 StoryBoard 绘制
类型 | 数量 |
---|---|
button | 23 |
stackView | 7 |
label | 1 |
- 每行
button
使用一个水平stackView
包裹, 所有button
行使用一个竖直stackView
包裹, 最终与label
并列.
- SwiftUI 版的计算器 UI 与 UIKit 版大体相同, 不同之处在于 SwiftUI 版完全使用代码定义, 在一些细节上比 UIKit 版更加精致
类型 | 数量 |
---|---|
Text | 24 |
Button | 23 |
HStack | 7 |
Spacer | 3 |
VStack | 2 |
Color | 1 |
ZStack | 1 |
设备 | 表达式 | 结果 |
---|---|---|
iPod touch(7th) | ![]() |
![]() |
iPod touch(7th) | ![]() |
![]() |
iPod touch(7th) | ![]() |
![]() |
iPhone 12 Pro Max | ![]() |
![]() |
iPhone 12 Pro Max | ![]() |
![]() |
iPhone 12 Pro Max | ![]() |
![]() |
iPad(8th) | ![]() |
![]() |
iPad(8th) | ![]() |
![]() |
iPad(8th) | ![]() |
![]() |
设备 | 表达式 | 结果 |
---|---|---|
iPod touch(7th) | ![]() |
![]() |
iPod touch(7th) | ![]() |
![]() |
iPod touch(7th) | ![]() |
![]() |
iPhone SE(2nd) | ![]() |
![]() |
iPhone SE(2nd) | ![]() |
![]() |
iPhone SE(2nd) | ![]() |
![]() |
iPhone 8 Plus | ![]() |
![]() |
iPhone 8 Plus | ![]() |
![]() |
iPhone 8 Plus | ![]() |
![]() |