【iOS】仿写计算器

文章目录

  • 前言
  • 使用Masonry在View中布局
  • 判错处理
  • 数据处理
  • git链接

前言

这次仿写计算器是第一次使用MVC设计模式写一个小demo,对于MVC设计模式可见这篇博客 【iOS】MVC设计模式。也是第一次使用Masonry库进行view的页面布局,关于Masonry的使用可见这篇博客【iOS】Masonry的简单使用。其次,关于计算器中对字符串处理、计算等逻辑问题主要用到了栈的思想,关于c语言中四则运算可见这篇博客 用栈实现四则运算。虽然是用Objective-C写,但是在OC中可以调用许多方法处理,可以更方便。

使用Masonry在View中布局

  • 关于整齐排列的16个按键可以使用循环创建button,只需使用不同tag值在后面调用指定的button,最下面的三个按键就可以分别单独创建button
  • 在使用Masonry约束时,注意不可约束条件过多造成冲突,我是使用了bottomleftwidthheight四个条件来进行约束的,widthheight因为每个按键形状大小都一样所以都是固定值,而bottomleft要根据每一行每一列进行计算
for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            _baseButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
            _baseButton.titleLabel.font = [UIFont systemFontOfSize:42];
            _baseButton.layer.cornerRadius = SIZE / 2;
            [_baseButton addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];
            _baseButton.tag = 204 + j + i * 4;
            [self addSubview:_baseButton];
            [_baseButton mas_makeConstraints:^(MASConstraintMaker* make) {
                make.bottom.equalTo(self).offset(-(90 + (SIZE + 15) * (i + 1)));
                make.left.equalTo(self).offset(15 + (SIZE + 15) * j);
                make.width.equalTo(@SIZE);
                make.height.equalTo(@SIZE);
            }];
            if (j < 3) {
                if (i < 3) {
                    [_baseButton setBackgroundColor:[UIColor colorWithWhite:0.15 alpha:1]];
                    [_baseButton setTitle:[NSString stringWithFormat:@"%d", i * 3 + j + 1]    forState:UIControlStateNormal];
                    [_baseButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
                } else {
                    [_baseButton setBackgroundColor:[UIColor lightGrayColor]];
                    [_baseButton setTitle:grayArray[j] forState:UIControlStateNormal];
                    [_baseButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
                }
            } else {
                [_baseButton setBackgroundColor:[UIColor colorWithRed:0.9 green:0.58 blue:0 alpha:1]];
                [_baseButton setTitle:orangeArray[i] forState:UIControlStateNormal];
                [_baseButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
            }
        }
    }

效果如下:

【iOS】仿写计算器_第1张图片

判错处理

  • 在按键的同时进行判定,如果表达式有误则赋给一个flag属性为1,最后在点击 “=” 时再进行判定,如果flag==1则表达式有误,屏幕上就会显示错误提示,不再进行计算。
  • 对除法式子,分母为0会报错;括号匹配不当会报错;运算符相连输入会报错等等
- (BOOL) isSymbolJudgeFlag:(NSString*)first :(NSString*)second {
    int firstFlag = 0;
    int secondFlag = 0;
    if ([first isEqualToString:@"+"] || [first isEqualToString:@"-"] || [first isEqualToString:@"×"] || [first isEqualToString:@"÷"]) {
        firstFlag = 1;
    }
    if ([second isEqualToString:@"+"] || [second isEqualToString:@"-"] || [second isEqualToString:@"×"] || [second isEqualToString:@"÷"]) {
        secondFlag = 1;
    }
    if ([first isEqualToString:@"÷"] && [second isEqualToString:@"0"]) {
        return true;
    }
    if ([first isEqualToString:@"("] && [second isEqualToString:@")"]) {
        return true;
    }
    if ([first isEqualToString:@"("] && ([second isEqualToString:@"+"] || [second isEqualToString:@"-"] || [second isEqualToString:@"×"] || [second isEqualToString:@"÷"])) {
        return true;
    }
    if ([second isEqualToString:@"("] && (![first isEqualToString:@"+"] && ![first isEqualToString:@"-"] && ![first isEqualToString:@"×"] && ![first isEqualToString:@"÷"] && ![first isEqualToString:@""])) {
        return true;
    }
    if (firstFlag == 1 && secondFlag == 1) {
        return true;
    } else {
        return false;
    }
}

数据处理

  • 根据MVC设计模式的要求,数据处理基本都在Model里完成
  • 将输入的表达式NSString类型传到model中,循环遍历每个字符进行运算数栈和运算符栈的存储,此处的栈使用NSMutable数组。
  • 将NSString类型转换成double类型使用double temp = [_tempNumberString doubleValue]方法
  • 删除结果多余的零时使用下面这个方法函数,传进的参数是NSString类型,返回的也是NSString类型
- (NSString*)removeFloatAllZeroByString:(NSString *)testNumber {
    
    NSString * outNumber = [NSString stringWithFormat:@"%@",@(testNumber.floatValue)];
    return outNumber;
}
  • 使用栈的具体操作如下
- (NSString*)getAnswer {
    _numberStack = [[NSMutableArray alloc] init];
    _symbolStack = [[NSMutableArray alloc] init];
    for (int i = 0; i < _printString.length;) {
        char tempChar = [_printString characterAtIndex:i];
        NSString *tempString =[[NSString alloc] initWithFormat:@"%c",tempChar];
        if (![self isSymbol:tempString]) {
            _tempNumberString = [[NSString alloc] init];
            while (![self isSymbol:tempString]) {
                _tempNumberString = [_tempNumberString stringByAppendingString:tempString];
                i++;
                char tempChar = [_printString characterAtIndex:i];
                tempString =[[NSString alloc] initWithFormat:@"%c",tempChar];
            }
            double temp = [_tempNumberString doubleValue];
            [_numberStack addObject:[NSNumber numberWithDouble:temp]];
        } else {
            if ([[_symbolStack lastObject] isEqualToString:@"("]) {
                if ([_printString characterAtIndex:i] == ')') {
                    [_symbolStack removeLastObject];
                } else {
                    char tempChar = [_printString characterAtIndex:i];
                    NSString *tempString =[[NSString alloc] initWithFormat:@"%c",tempChar];
                    [_symbolStack addObject:tempString];
                }
                i++;
            } else {
                char tempChar = [_printString characterAtIndex:i];
                NSString *tempString =[[NSString alloc] initWithFormat:@"%c",tempChar];
                if (![self precede:[_symbolStack lastObject] :tempString]) {
                    [_symbolStack addObject:tempString];
                    i++;
                } else {
                    NSNumber* bTemp = [_numberStack lastObject];
                    double b = [bTemp doubleValue];
                    [_numberStack removeLastObject];
                    NSNumber* aTemp = [_numberStack lastObject];
                    double a = [aTemp doubleValue];
                    [_numberStack removeLastObject];
                    NSString* s = [_symbolStack lastObject];
                    [_symbolStack removeLastObject];
                    double temp = [self calculation:a :b :s];
                    [_numberStack addObject:[NSNumber numberWithDouble:temp]];
                    if ([_printString characterAtIndex:i] == '#' && _symbolStack.count == 0) {
                        i++;
                    }
                }
            }
        }
    }
    double answerNumber = [[_numberStack lastObject] doubleValue];
    _answer = [self switchDoubleToNSStringWithoutZero:answerNumber];
    _answer = [self removeFloatAllZeroByString:_answer];
    return _answer;
}

git链接

git地址

你可能感兴趣的:(ios)