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 {
    [email protected]"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;
    [email protected]"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;
    [email protected]"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;
    [email protected]"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;
    [email protected]"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;
    [email protected]"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){
        //输出错误提示
        [email protected]"错误";
        _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来进行设置,如下图所示:

原文地址:https://www.cnblogs.com/Solist/p/10352789.html

时间: 2024-11-09 02:00:13

XCode Interface Builder开发——2的相关文章

【转 iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束

原文网址:http://blog.csdn.net/pucker/article/details/41843511 上一篇文章<iOS 8界面自动布局系列-1>简要介绍了iOS界面布局方式的前世今生.本篇文章将详细介绍如何使用自动布局实现不同屏幕尺寸的适配. 添加自动布局约束(下文简称约束)有以下三种方式: 使用Xcode的Interface Builder界面设计器添加并设置约束 通过代码逐条添加约束 通过可视化格式语言VFL添加约束 本文将以一个简单的例子来演示如何使用这几种方式添加约束,

Cocoa、Foundation、UIKit、Objective-c、XCode、Interface Builder的概念

Cocoa 是在Mac OS X系统上原生的一个编译环境.他包含两个框架,其实就是一系列的类库,Foundation和AppKit. 在你的iPhone等掌上设备上,使用的则是他的一个子类 - Cocoa Touch.他所支持的Foundation框架与Cocoa相同,但他的用户图形类库为UIKit,它是为掌上设备特殊设计,提供了你设备上的界面. Cocoa Touch与Cocoa一个比较鲜明的区别就是Cocoa Touch并不支持垃圾回收机制,这就意味着你必须在你的代码里管理好你的内存. Fo

转:Cocoa、Foundation、UIKit、Objective-c、XCode、Interface Builder的概念

Cocoa 是在Mac OS X系统上原生的一个编译环境.他包含两个框架,其实就是一系列的类库,Foundation和AppKit. 在你的iPhone等掌上设备上,使用的则是他的一个子类 - Cocoa Touch.他所支持的Foundation框架与Cocoa相同,但他的用户图形类库为UIKit,它是为掌上设备特殊设计,提供了你设备上的界面. Cocoa Touch与Cocoa一个比较鲜明的区别就是Cocoa Touch并不支持垃圾回收机制,这就意味着你必须在你的代码里管理好你的内存. Fo

[转]使用 Xcode 5 和 Interface Builder创建 Hello World App

转载地址:http://www.ithome.me/archives/581.html 使用 Xcode 5 和 Interface Builder创建 Hello World App 发表回复 当xcode 5发布后,相比之前的版本变化很大,大家可能会有一些疑问: 我跟随教程学习但是发现程序在 Xcode 5 中不再受支持. Interface Builder在哪儿? 我如何去创建一个XIB 文件? 这样的例子不胜枚举. Xcode 5 推荐使用Storyboard 而不是 Interface

iOS开发-Interface Builder的前世今生

Interface Builder,是用于苹果公司Mac OS X操作系统的软件开发程序,Xcode套件的一部分,于1988年创立.它的创造者Jean-Marie Hullot自称是“一个热爱旅行.充满激情的摄影师”,本篇分享Hullot热爱技术的那一面——创造Interface Builder的过程. 因势而动 1981年, Jean-Marie Hullot拿到巴黎第十一大学的计算机科学博士资格后,开始了法国国家信息与自动化研究所(INRIA)的研究生活. Jean-Marie Hullot

iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束

http://blog.csdn.net/pucker/article/details/41843511 上一篇文章<iOS 8界面自动布局系列-1>简要介绍了iOS界面布局方式的前世今生.本篇文章将详细介绍如何使用自动布局实现不同屏幕尺寸的适配. 添加自动布局约束(下文简称约束)有以下三种方式: 使用Xcode的Interface Builder界面设计器添加并设置约束 通过代码逐条添加约束 通过可视化格式语言VFL添加约束 本文将以一个简单的例子来演示如何使用这几种方式添加约束,如下图所示

代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧

代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧 最近接触了几个刚入门的iOS学习者,他们之中存在一个普遍和困惑和疑问,就是应该如何制作UI界面.iOS应用是非常重视用户体验的,可以说绝大多数的应用成功与否与交互设计以及UI是否漂亮易用有着非常大的关系.而随着iOS开发发展至今,可以说在UI制作上大家逐渐分化为了三种主要流派:使用代码手写UI及布局:使用单个xib文件组织viewController或者view:使用StoryBoard来通过

提高Interface Builder高效工作的8个技巧

本文转载至 http://www.cocoachina.com/ios/20141106/10151.html iOS开发Interface Builder 本文译自:8 Tips for working effectively with Interface Builder(需FQ) 先来看看目录: 介绍 使view的Size与view中的Content相适应 按住option键—观察所选中view与另外view边缘之间的距离 Editor –> Embed In View, Unembed:

xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧

最近接触了几个刚入门的iOS学习者,他们之中存在一个普遍和困惑和疑问,就是应该如何制作UI界面.iOS应用是非常重视用户体验的,可以说绝大多数的应用成功与否与交互设计以及UI是否漂亮易用有着非常大的关系.而随着iOS开发发展至今,可以说在UI制作上大家逐渐分化为了三种主要流派:使用代码手写UI及布局:使用单个xib文件组织viewController或者view:使用StoryBoard来通过单个或很少的几个(关于这点稍后会进行展开)文件构建全部UI.应该使用哪种方式来制作UI已经是iOS开发中