XCode Interface Builder开发——2
XCode Interface Builder开发——2
简单的练手项目--仿苹果自备的计算器
简介
制作一个简易功能的计算器并非难事,但是其中要考虑的不同情况却仍有许多,稍不留神就会踩坑。
例如:
- 在输入完运算符后如果直接输入负号或者小数点的情况
- 连续运算的情况
- 在输入等号后继续运算或直接输入数字进行下一轮的计算的情况
- 小数情况下,精度带来的问题
- ... ...
设计思想
按照编译原理中的三元式的思想,为了区分输入的第一运算对象和第二运算对象,我分别将其命名为firstNum和secondNum,并将它们作为ViewController的属性。并且为了区分计算器当前处于何种模式下(点击小数点后的小数模式、点击负号的负号模式、待第二个数输入的模式等等),我又将各种不同的BOOL型变量设置为其属性供各种方法下调用。
话不多说,看代码:
//
// ViewController.m
// MyFirstApp
//
// Created by solist on 2019/1/31.
// Copyright © 2019 solist. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic) double firstNum;
@property(nonatomic) double secondNum;
@property(nonatomic) BOOL fistNumIsActive;
@property(nonatomic) BOOL isWaitingForSecondNum;
@property(nonatomic) BOOL isTappingSecondNum;
@property(nonatomic) BOOL isNegativeNum;
@property(nonatomic) BOOL isBeginNegativeNum;
@property(nonatomic) BOOL isAfterEqual;
@property(nonatomic) BOOL isTappingDecimals;
@property(nonatomic) float decimalRecord;
@property(nonatomic,weak) NSString *operation;
@property (weak, nonatomic) IBOutlet UITextField *result;
@end
@implementation ViewController
//初始化属性
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_firstNum=0.0;
_secondNum=0.0;
_fistNumIsActive=YES;
_isTappingSecondNum=NO;
_isWaitingForSecondNum=NO;
_isNegativeNum=NO;
_isBeginNegativeNum=NO;
_isAfterEqual=NO;
_isTappingDecimals=NO;
_decimalRecord=0.1;
[self updateScreen:0.0];
}
//更新屏幕数据(对象方法,在不同的按钮响应事件中调用)
-(void)updateScreen:(double) num{
_result.text=[NSString stringWithFormat:@"%f", num];
}
//清空(与清空“AC”的Btn连接)
- (IBAction)AC {
_result.text=@"0";
_firstNum=0.0;
_secondNum=0.0;
//更新数据
[self updateScreen:_firstNum];
_fistNumIsActive=YES;
_isWaitingForSecondNum=NO;
_isTappingSecondNum=NO;
_isNegativeNum=NO;
_isBeginNegativeNum=NO;
_isAfterEqual=NO;
_isTappingDecimals=NO;
_decimalRecord=0.1;
_operation=@"nil";
}
//正负数转换(与负号“-”的Btn连接)
- (IBAction)pnConversion{
if(_isWaitingForSecondNum||_firstNum==0){
_isBeginNegativeNum=!_isBeginNegativeNum;
_isNegativeNum=!_isNegativeNum;
//_secondNum=0;
_isWaitingForSecondNum=NO;
if(_isBeginNegativeNum&&!_isAfterEqual){
[self updateScreen:-0.0];
}
else if(_isAfterEqual){
_firstNum=-_firstNum;
[self updateScreen:_firstNum];
}
else{
[self updateScreen:+0.f];
}
}
else{
_isNegativeNum=!_isNegativeNum;
if(!_isTappingSecondNum){
//修改第一个数的符号位
_firstNum=0-_firstNum;
[self updateScreen:_firstNum];
}
else{
if(_fistNumIsActive){
//当修改数为结果时
//修改第一个数的符号位
_firstNum=0-_firstNum;
[self updateScreen:_firstNum];
}
else{
//修改第二个数的符号位
_secondNum=0-_secondNum;
if(_firstNum==0){
_firstNum=-0.0;
}
[self updateScreen:_secondNum];
}
}
}
}
//百分号转换(与百分号“%”的Btn连接)
- (IBAction)percentageConversion {
if(!_isTappingSecondNum)
{
//将第一个数改为百分数
_firstNum=_firstNum/100.0;
[self updateScreen:_firstNum];
}
else{
if(_fistNumIsActive){
//当修改数为结果时
//将第一个数改为百分数
_firstNum=_firstNum/100.0;
[self updateScreen:_firstNum];
}
else{
//将第二个数改为百分数
_secondNum=_secondNum/100.0;
[self updateScreen:_secondNum];
}
}
}
//除法(与乘号“x”的Btn连接)
- (IBAction)divide {
//取消小数功能
_decimalRecord=0.1;
//1、输入等号后继续输入的情况
if(_isAfterEqual){
_isAfterEqual=!_isAfterEqual;
}
_isNegativeNum=NO;
_isBeginNegativeNum=NO;
//2、连续输入的情况
if(_isTappingSecondNum){
NSArray *operationsArray = @[@"add", @"sub", @"multi",@"divide"];
//获得上次的运算符
NSUInteger item = [operationsArray indexOfObject:_operation];
float theResult;
switch (item) {
case 0:
theResult=_firstNum+_secondNum;
break;
case 1:
theResult=_firstNum-_secondNum;
break;
case 2:
theResult=_firstNum*_secondNum;
break;
case 3:
theResult=_firstNum/_secondNum;
default:
break;
}
//在屏幕上输出结果
[self updateScreen:theResult];
//更新firstNum
_firstNum=theResult;
}
//更新firstNum
_firstNum=[_result.text floatValue];
//修改运算符号,并通知下一步为输入secondNum
_isWaitingForSecondNum=YES;
_fistNumIsActive=NO;
_secondNum=0;
_operation=@"divide";
_isTappingSecondNum=NO;
_isTappingDecimals=NO;
}
//乘法(与乘号“✖️”的Btn连接)
- (IBAction)multi {
//取消小数功能
_decimalRecord=0.1;
if(_isAfterEqual){
_isAfterEqual=!_isAfterEqual;
}
_isNegativeNum=NO;
_isBeginNegativeNum=NO;
//连续输入的情况
if(_isTappingSecondNum){
NSArray *operationsArray = @[@"add", @"sub", @"multi",@"divide"];
//获得上次的运算符
NSUInteger item = [operationsArray indexOfObject:_operation];
float theResult;
switch (item) {
case 0:
theResult=_firstNum+_secondNum;
break;
case 1:
theResult=_firstNum-_secondNum;
break;
case 2:
theResult=_firstNum*_secondNum;
break;
case 3:
theResult=_firstNum/_secondNum;
default:
break;
}
//在屏幕上输出结果
[self updateScreen:theResult];
//更新firstNum
_firstNum=theResult;
}
//更新firstNum
_firstNum=[_result.text floatValue];
//修改运算符号,并通知下一步为输入secondNum
_isWaitingForSecondNum=YES;
_fistNumIsActive=NO;
_secondNum=0;
_operation=@"multi";
_isTappingSecondNum=NO;
_isTappingDecimals=NO;
}
//减法(与减号“-”的Btn连接)
- (IBAction)sub {
//取消小数功能
_decimalRecord=0.1;
if(_isAfterEqual){
_isAfterEqual=!_isAfterEqual;
}
_isNegativeNum=NO;
_isBeginNegativeNum=NO;
//连续输入的情况
if(_isTappingSecondNum){
NSArray *operationsArray = @[@"add", @"sub", @"multi",@"divide"];
//获得上次的运算符
NSUInteger item = [operationsArray indexOfObject:_operation];
float theResult;
switch (item) {
case 0:
theResult=_firstNum+_secondNum;
break;
case 1:
theResult=_firstNum-_secondNum;
break;
case 2:
theResult=_firstNum*_secondNum;
break;
case 3:
theResult=_firstNum/_secondNum;
default:
break;
}
//在屏幕上输出结果
[self updateScreen:theResult];
//更新firstNum
_firstNum=theResult;
}
//更新firstNum
_firstNum=[_result.text floatValue];
//修改运算符号,并通知下一步为输入secondNum
_isWaitingForSecondNum=YES;
_fistNumIsActive=NO;
_secondNum=0;
_operation=@"sub";
_isTappingSecondNum=NO;
_isTappingDecimals=NO;
}
//加法(与“+”的Btn连接)
- (IBAction)add {
//取消小数功能
_decimalRecord=0.1;
if(_isAfterEqual){
_isAfterEqual=!_isAfterEqual;
}
_isNegativeNum=NO;
_isBeginNegativeNum=NO;
//连续输入的情况
if(_isTappingSecondNum){
NSArray *operationsArray = @[@"add", @"sub", @"multi",@"divide"];
//获得上次的运算符
NSUInteger item = [operationsArray indexOfObject:_operation];
float theResult;
switch (item) {
case 0:
theResult=_firstNum+_secondNum;
break;
case 1:
theResult=_firstNum-_secondNum;
break;
case 2:
theResult=_firstNum*_secondNum;
break;
case 3:
theResult=_firstNum/_secondNum;
default:
break;
}
//在屏幕上输出结果
[self updateScreen:theResult];
//更新firstNum
_firstNum=theResult;
}
//更新firstNum
_firstNum=[_result.text floatValue];
//修改运算符号,并通知下一步为输入secondNum
_isWaitingForSecondNum=YES;
_fistNumIsActive=NO;
_secondNum=0;
_operation=@"add";
_isTappingSecondNum=NO;
_isTappingDecimals=NO;
}
//等号(与等号的Btn连接)
- (IBAction)equal {
//取消小数功能
_decimalRecord=0.1;
_isNegativeNum=NO;
_isBeginNegativeNum=NO;
_isTappingSecondNum=NO;
NSArray *operationsArray = @[@"add", @"sub", @"multi",@"divide"];
NSUInteger item = [operationsArray indexOfObject:_operation];
//特殊情况:secondNum未输入,按secondNum=firstNum
if(_isWaitingForSecondNum){
_secondNum=_firstNum;
}
//进行计算
float theResult;
BOOL error=NO;
switch (item) {
case 0:
theResult=_firstNum+_secondNum;
break;
case 1:
theResult=_firstNum-_secondNum;
break;
case 2:
theResult=_firstNum*_secondNum;
break;
case 3:
if(_secondNum==0.0){
error=YES;
}else{
theResult=_firstNum/_secondNum;
}
break;
default:
//当无运算符时,即清空后只输入了firstNum
theResult=_firstNum;
break;
}
//在屏幕上输出结果
if(error){
//输出错误提示
_result.text=@"错误";
_firstNum=0.0;
}
else{
[self updateScreen:theResult];
}
//为下一次计算做准备
_firstNum=theResult;
_secondNum=0.0;
_fistNumIsActive=YES;
_isWaitingForSecondNum=YES;
_isTappingSecondNum=NO;
_isBeginNegativeNum=NO;
_isNegativeNum=NO;
_isAfterEqual=YES;
}
//点击数字1(与数字1的Btn连接)
- (IBAction)_1 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-1.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-1.0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+1.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+1.0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-1.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-1.f;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+1.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+1.f;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
- (IBAction)_2 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-2.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-2.0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+2.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+2.0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-2.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-2.f;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+2.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+2.f;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
- (IBAction)_3 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-3.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-3.0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+3.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+3.0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-3.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-3.f;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+3.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+3.f;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
- (IBAction)_4 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-4.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-4.0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+4.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+4.0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-4.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-4.f;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+4.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+4.f;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
- (IBAction)_5 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-5.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-5.0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+5.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+5.0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-5.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-5.f;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+5.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+5.f;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
- (IBAction)_6 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-6.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-6.0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+6.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+6.0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-6.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-6.f;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+6.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+6.f;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
- (IBAction)_7 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-7.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-7.0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+7.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+7.0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-7.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-7.f;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+7.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+7.f;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
- (IBAction)_8 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-8.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-8.0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+8.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+8.0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-8.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-8.f;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+8.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+8.f;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
- (IBAction)_9 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-9.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-9.0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+9.0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+9.0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-9.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-9.f;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+9.f*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+9.f;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
- (IBAction)_0 {
//进行下一轮的计算
if(_isAfterEqual){
[self AC];
}
if(_fistNumIsActive){
//正在输入第一个数
if(_isNegativeNum){
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum-0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0-0;
}
}
else{
if(_isTappingDecimals){
//输入了小数点模式后
_firstNum=_firstNum+0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_firstNum=_firstNum*10.0+0;
}
}
//更新屏幕
[self updateScreen:_firstNum];
_isWaitingForSecondNum=NO;
}
else{
//正在输入第二个数
_isTappingSecondNum=YES;
if(_isNegativeNum){
//_secondNum=_secondNum*10.f-1.f;
if(_isTappingDecimals){
_secondNum=_secondNum-0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f-0;
}
}
else{
//_secondNum=_secondNum*10.f+1.f;
if(_isTappingDecimals){
_secondNum=_secondNum+0*_decimalRecord;
_decimalRecord*=0.1;
}
else{
_secondNum=_secondNum*10.f+0;
}
}
//更新屏幕
[self updateScreen:_secondNum];
_isWaitingForSecondNum=NO;
}
}
//小数点(与小数点“.”的Btn连接)
- (IBAction)decimalPoint {
//当输入完小数点再输入数字后再次输入小数点则无效
if(_decimalRecord==0.1f){
_isTappingDecimals=!_isTappingDecimals;
}
//判断当前数字是否为整数
double tmp=[_result.text doubleValue];
double eps = 1e-10;
BOOL isInteger = tmp - floor(tmp) < eps;
if(_isTappingDecimals&&isInteger){
NSString*content =_result.text;
NSMutableAttributedString*attributeString = [[NSMutableAttributedString alloc]initWithString:content];
NSUInteger Loc = [[attributeString string] rangeOfString:@"."].location;
// 需要改变的区间
NSRange range = NSMakeRange(Loc, 1);
// 改变小数点颜色
[attributeString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range];
// 为label添加Attributed
[_result setAttributedText:attributeString];
}
else{
NSString*content =_result.text;
NSMutableAttributedString*attributeString = [[NSMutableAttributedString alloc]initWithString:content];
NSUInteger Loc = [[attributeString string] rangeOfString:@"."].location;
// 需要改变的区间
NSRange range = NSMakeRange(Loc, 1);
// 改变小数点颜色
[attributeString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:range];
// 为label添加Attributed
[_result setAttributedText:attributeString];
}
//若按完j运算符再点击小数点时,更新屏幕显示(+0或-0)
if(_isWaitingForSecondNum&&_isTappingDecimals){
[self updateScreen:0.0];
NSString*content =_result.text;
NSMutableAttributedString*attributeString = [[NSMutableAttributedString alloc]initWithString:content];
NSUInteger Loc = [[attributeString string] rangeOfString:@"."].location;
// 需要改变的区间
NSRange range = NSMakeRange(Loc, 1);
// 改变小数点颜色
[attributeString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range];
// 为label添加Attributed
[_result setAttributedText:attributeString];
}
}
@end
成品图
遇到的坑
之前我将firstNum和secondNum的类型设置的是float,在一开始的调试过程中一直未出现问题,但是当写小数功能时发现了问题,当我利用nsLog打印出结果时发现:111.01+0.001的结果不等于111.011而是等于111.01098......,后来发现是因为float自身的精度问题(7位有效数字),在将float修改为double(16位有效数字)后有所改善,但遇到位数更多的小数仍会出现该问题。
关于精度的问题,我觉得这个网站讲的不错,可以参考这个网站:https://www.jianshu.com/p/9cbed21f37fe
对于需要更多精确计算的方法,也可以试试封装的NSDecimalNumber类,在这里因为没怎么用过,就不说了。
总体来说,这次设计遇到的问题主要集中在逻辑设计,需要考虑到用户的误操作(被除数为0等情况)以及数字精度问题,其他来说没有难度,可以当作IOS的初学练手。
按钮的圆形设计
我主要是通过修改按钮的layer.cornerRadius属性来实现的,这里我提供一个简单的方法,直接通过storyBoard来进行设置,如下图所示:
XCode Interface Builder开发——2的更多相关文章
- XCode Interface Builder开发——1
XCode Interface Builder开发--1 创建Xcode项目 选择第二个选项 选择Single View App,点击Next 设置完后点击Next Xcode基本面板 导航面板 工具 ...
- ***Xcode Interface Builder或Storyboard中可建立那两种连接?
在Xcode Interface Builder或Storyboard中,可建立到输出口(IBOutlet)和操作(方法,IBAction)的连接. IBOutlet are for output C ...
- IOS 使用Interface Builder开发界面入门与技巧
引言: 通过Interface Builder(简称IB)来制作界面一直是iOS开发界饱受争议的方式.主要争议的话题是不太适合团队协作开发,再就是对IB的使用比较生疏,觉得IB只能完成一些很简单的功能 ...
- 苹果开发工具:Xcode和Interface Builder
摘要:在Mac OS X上开发,首选Xcode继承开发环境.本文对开发工具套件中最重要的Xcode和Interface Builder两个工具做了简要介绍,并提供<苹果开发工具概述>PDF ...
- iOS开发工具Xcode:Interface Builder
简介: Interface Builder(IB)是Mac OS X平台下用于设计和测试用户界面(GUI)的应用程序(非开源).为了生成GUI,IB并不是必需的,实际上Mac OS X下所有的用户界面 ...
- [转]使用 Xcode 5 和 Interface Builder创建 Hello World App
转载地址:http://www.ithome.me/archives/581.html 使用 Xcode 5 和 Interface Builder创建 Hello World App 发表回复 当x ...
- iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束
http://blog.csdn.net/pucker/article/details/41843511 上一篇文章<iOS 8界面自动布局系列-1>简要介绍了iOS界面布局方式的前世今生 ...
- 【转 iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束
原文网址:http://blog.csdn.net/pucker/article/details/41843511 上一篇文章<iOS 8界面自动布局系列-1>简要介绍了iOS界面布局方式 ...
- 转:Cocoa、Foundation、UIKit、Objective-c、XCode、Interface Builder的概念
Cocoa 是在Mac OS X系统上原生的一个编译环境.他包含两个框架,其实就是一系列的类库,Foundation和AppKit. 在你的iPhone等掌上设备上,使用的则是他的一个子类 - Coc ...
随机推荐
- CSRF与平行越权的区别
.CSRF攻击者不需要登录,越权攻击者也得登录,只是没有做针对性的控制: .CSRF攻击者自己不访问受攻击页面,诱导受害者在登录被攻击系统后点击攻击页面:越权攻击者可以直接访问受攻击页面: .CSRF ...
- chcp437 转换英语,在西班牙语系统中无效
https://social.technet.microsoft.com/Forums/en-US/9c772011-5094-4df0-bf73-7140bf91673b/chcp-command- ...
- lodctr /R 失败的情况
I've resolved with the following steps: PS C:\Windows\system32> cmd Microsoft Windows [Version 6. ...
- Spring Cloud OpenFeign使用教程
文章目录 Spring Cloud OpenFeign Demo 怎么配置OpenFeignServer 怎么配置OpenFeignClient 多个参数传递问题 FeignClient的日志问题 多 ...
- VulnHub靶场学习_HA: Chanakya
HA-Chanakya Vulnhub靶场 下载地址:https://www.vulnhub.com/entry/ha-chanakya,395/ 背景: 摧毁王国的策划者又回来了,这次他创造了一个难 ...
- 汇编 之 win10 下安装dosbox 和 MASM
所需工具链接: 链接:https://pan.baidu.com/s/1nenMsSdgEkeRKc6wh9DQRA 提取码:1r89 只需要以下两个工具 安装dosbox 和MASM步骤 (1)解压 ...
- 自动驾驶汽车数据不再封闭,Uber 开源新的数据可视化系统
日前,Uber 开源了基于 web 的自动驾驶可视化系统(AVS),称该系统为自动驾驶行业带来理解和共享数据的新方式.AVS 由Uber旗下负责自动驾驶汽车研发的技术事业群(ATG)开发,目前该系统已 ...
- dlopen failed: empty/missing DT_HASH in "libx.so" (built with --hash-style=gnu?)
崩溃日志内容: java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH in "libxxxx.so&quo ...
- CF思维联系–CodeForces-217C C. Formurosa(这题鸽了)
ACM思维题训练集合 The Bytelandian Institute for Biological Research (BIBR) is investigating the properties ...
- CodeForces - 260B
A recently found Ancient Prophesy is believed to contain the exact Apocalypse date. The prophesy is ...