昨晚心血来潮,想做个计算器来玩玩。说写就写,结果速度比意料中快,大概一个多小时码完,今天花了一些零散时间优化了下,这个demo也算基本完成了。
概述
这次练习用到的控件如下:
UILabel
UIButton
OC基础知识,涉及的是:
NSMutableString
block
NSString
NSArray
实现思路
感觉有点草率,没多做考虑,大概是以下几点:
点击数字按钮时,结果以追加形式显示数字文本
存在运算命令的时候,则清空之前的结果文本,重新追加数字文本
使用一个临时的变量来保存清空之前的值,计算时再将该变量与当前的文本值进行计算
计算器的功能并不完善,这次只实现点击了“=”才会计算结果。印象中去大排档吃饭,结账时店里那大妈都是狂敲“+”键的。
准备
这里我设置了以下三个属性,按钮事件方面,其实将清空和负数按钮的事件,跟运算命令按钮事件集合在一起也是可以的,通过按钮的tag属性来判断就行了:
- (IBAction)numClickBtn:(UIButton *)sender; /**< 数字按钮事件*/
- (IBAction)clearBtn:(UIButton *)sender; /**< 清空按钮事件*/
- (IBAction)commandBtn:(UIButton *)sender; /**< 运算命令按钮事件*/
- (IBAction)negativeBtn:(UIButton *)sender; /**< 负数按钮事件*/
@property (nonatomic, readwrite, assign) NSUInteger opreateBtnTag; /**< 运算命令标识位*/
@property (nonatomic, readwrite, getter=hasCommand) BOOL command; /**< 当前是否有运算命令*/
@property (nonatomic, readwrite, copy) NSString *tempResult; /**< 临时结果值*/
实现
程序启动
程序启动后,将_command设置为NO,_tempResult设置为0:
- (void)viewDidLoad {
[super viewDidLoad];
_command = NO;
_tempResult = @"0";
}
数字按钮事件
首先看点击数字按钮时是怎么处理的:
#pragma mark 数字按钮事件
- (IBAction)numClickBtn:(UIButton *)sender {
// 没有运算命令
if (!self.hasCommand) {
if ([_resultLabel.text isEqualToString:@"0"]) {
_resultLabel.text = sender.currentTitle;
} else if (_resultLabel.text.length < 10) {
_resultLabel.text = [_resultLabel.text stringByAppendingString:sender.currentTitle];
}
// 存在运算命令
} else {
_resultLabel.text = sender.currentTitle;
}
_command = NO;
}
当前没有点击运算命令的情况下,分两种情况:
UILabel为0,则直接设置数字按钮标题为UILabel的文本值
UILabel不为0,则让UILabel文本值直接追加数字按钮标题就行了。
如果存在运算命令,那么UILabel直接设置为数字按钮标题。
运算命令事件
#pragma mark 运算命令
- (IBAction)commandBtn:(UIButton *)sender {
switch (sender.tag) {
case kCalculatorAddition:
case kCalculatorSubtraction:
case kCalculatorMultiplication:
case kCalculatorDivision:
case kCalculatorRemainder:
_tempResult = [NSString stringWithString:_resultLabel.text];
_opreateBtnTag = sender.tag;
_command = YES;
break;
case kCalculatorEqualSign:
[self calculate];
break;
case kCalculatorDecimalPoint:
[self dotMethod:sender];
}
}
#pragma mark 计算结果
- (void)calculate {
switch (_opreateBtnTag) {
case kCalculatorAddition:
{
[self opreate:^float{
return [_tempResult floatValue] + [_resultLabel.text floatValue];
}];
}
break;
case kCalculatorSubtraction:
{
[self opreate:^float{
return [_tempResult floatValue] - [_resultLabel.text floatValue];
}];
}
break;
case kCalculatorMultiplication:
{
[self opreate:^float{
return [_tempResult floatValue] * [_resultLabel.text floatValue];
}];
}
break;
case kCalculatorDivision:
{
if (![_resultLabel.text isEqualToString:@"0"]) {
[self opreate:^float{
return [_tempResult floatValue] / [_resultLabel.text floatValue];
}];
}
}
break;
case kCalculatorRemainder:
{
if (![_resultLabel.text isEqualToString:@"0"]) {
[self opreate:^float{
return [_tempResult intValue] % [_resultLabel.text intValue];
}];
}
}
break;
default:
break;
}
_opreateBtnTag = 0;
}
#pragma mark 计算后显示结果block
- (void)opreate:(float(^)()) block{
NSString *tempStr = [NSString stringWithFormat:@"%.2f", block()];
if (tempStr.length > 10) {
_resultLabel.text = @"o(╯□╰)o...";
} else {
NSArray *arr = [tempStr componentsSeparatedByString:@"."];
if ([arr[1] isEqualToString:@"00"]) {
_resultLabel.text = arr[0];
} else if ([arr[1] hasSuffix:@"0"]) {
NSMutableString *str = [NSMutableString stringWithString:arr[1]];
[str deleteCharactersInRange:NSMakeRange((str.length-1), 1)];
_resultLabel.text = [NSString stringWithFormat:@"%@.%@", arr[0], str];
} else {
_resultLabel.text = tempStr;
}
}
}
这里枚举常量对应每个UIButton的tag属性,计算结果时,采用了block的方法,因为只是运算命令不一样,对结果显示的处理都是一样的,所以将运算部分的代码作为参数传递到指定方法opreate中,避免过多的重复代码。
小数点按钮事件
#pragma mark 小数点事件
- (void)dotMethod:(UIButton *)sender {
// 当前无运算命令
if (!_command) {
// 不存在小数点、或是当前_resultLabel为0
if ([_resultLabel.text rangeOfString:@"."].location == NSNotFound || [_resultLabel.text isEqualToString:@"0"]) {
_resultLabel.text = [NSString stringWithFormat:@"%@%@", _resultLabel.text, @"."];
}
// 存在运算命令时
} else {
_resultLabel.text = @"0.";
}
_command = NO;
}
正负数按钮事件
#pragma mark 正负数按钮
- (IBAction)negativeBtn:(UIButton *)sender {
// 当前已为负数时
if ([_resultLabel.text hasPrefix:@"-"]) {
NSMutableString *numStr = [NSMutableString stringWithString:_resultLabel.text];
[numStr deleteCharactersInRange:NSMakeRange(0, 1)];
_resultLabel.text = numStr;
// 当前数值不为0或没有负号时,添加负号
} else if (![_resultLabel.text isEqualToString:@"0"]) {
_resultLabel.text = [NSString stringWithFormat:@"-%@", _resultLabel.text];
}
}
清空按钮事件
#pragma mark 清零按钮
- (IBAction)clearBtn:(UIButton *)sender {
_resultLabel.text = @"0";
_tempResult = @"0";
}
程序运行结果图