XCode Interface Builder開發——2

XCode Interface Builder開發——2app


簡單的練手項目--仿蘋果自備的計算器

簡介

製做一個簡易功能的計算器並不是難事,可是其中要考慮的不一樣狀況卻仍有許多,稍不留神就會踩坑。
例如:ide

  • 在輸入完運算符後若是直接輸入負號或者小數點的狀況
  • 連續運算的狀況
  • 在輸入等號後繼續運算或直接輸入數字進行下一輪的計算的狀況
  • 小數狀況下,精度帶來的問題
  • ... ...

設計思想

按照編譯原理中的三元式的思想,爲了區分輸入的第一運算對象和第二運算對象,我分別將其命名爲firstNum和secondNum,並將它們做爲ViewController的屬性。而且爲了區分計算器當前處於何種模式下(點擊小數點後的小數模式、點擊負號的負號模式、待第二個數輸入的模式等等),我又將各類不一樣的BOOL型變量設置爲其屬性供各類方法下調用。網站


話很少說,看代碼:ui

//
//  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;
    
    //一、輸入等號後繼續輸入的狀況
    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=@"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的初學練手。atom


按鈕的圓形設計

我主要是經過修改按鈕的layer.cornerRadius屬性來實現的,這裏我提供一個簡單的方法,直接經過storyBoard來進行設置,以下圖所示:
設計

相關文章
相關標籤/搜索