基於iOS的簡單計算器(二)

接上一篇基於iOS的簡單計算器(一)皆爲po主iOS課程的實驗內容。git

新增界面

  1. 高級計算器:可以進行一些高級的運算好比三角函數、階乘、對數等。github

  2. 體質計算器:獲取用戶的身高體重後,反饋用戶的體質指數。express

須要完成的功能

  1. 多場景切換segmentfault

  2. 高級計算器api

  3. 體質計算器app

  4. 設備鎖屏ide

  5. 畫圖:在體質計算器中的輸出結果上添加矩形邊框函數

  6. 控制屏幕顯示的字符串的長度spa

多場景切換

  • 場景:在故事板中,場景指單一視圖控制器及視圖3d

  • 場景過渡:在兩個場景之間和管理兩個場景的過渡。

  1. 拖動一個ViewController

  2. 新建一個UIViewController類SecondViewController,與前面的ViewController創建聯繫
    創建視圖控制器的聯繫

  3. 爲了在兩個視圖控制器之間通信,設定的用於高級計算的類的實例應該放在聲明之中//在.m文件中的話是private的

  4. 設定一個屬性screen,用於在視圖控制器之間通信

  5. 添加導航控制器Navigation Controller,創建導航控制器和已經作好的兩個視圖控制器的聯繫。注意:使用導航控制器作場景過渡,只能選擇push
    場景過渡

  6. 注意:在segue發起的時候,要作一些準備工做://爲了數據傳遞

    • 選中一個segue,先對其命名//可能有多個場景切換,須要判斷是哪一個

    • 在第一個場景中覆蓋prepareForSegue:方法。
      如下代碼的大意是,咱們先作判斷,若是該場景過渡是要進入高級計算器的視圖,則將第一個場景的advancedCalculator實例對象傳給第二個場景//注意要導入第二個視圖控制器的頭文件

      -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
                {
                    //把advanced的實例對象傳給第二個場景
                    if ([segue.identifier isEqualToString:@"SecondScene"]){//判斷是不是第二個場景
                        if ([segue.destinationViewController isKindOfClass:[SecondViewController class]]) {//判斷目的視圖控制器
                            SecondViewController *svc = (SecondViewController *)segue.destinationViewController;
                            svc.calculator = self.calculator;//僅傳遞了內容
                        }
                    }    
                }
  7. 在兩個視圖控制器中,都要將結果顯示在屏幕中,因此在兩個視圖控制器的viewWillAppear方法中,都要添加以下代碼

    self.inputText.text = self.calculator.screen;//從另外一個場景傳遞回來
  8. 注意,每次計算以後,既要修改屏幕上輸出的值,也要修改用於傳遞的screen屬性的值

高級計算器

  1. 添加一個高級計算的界面

  2. 添加一個用於高級計算的Model。因爲能夠用以前寫好的Calculate類,因此新建的類繼承自該類,而後只要再添加一些用於高級計算的方法便可。實現高級計算的方法不少,這裏用的是C語言的math庫中的函數

  3. 諸如括號、e、pi之類的按鈕,因爲咱們須要獲取按鈕上的值,來顯示在結果上,因此咱們須要創建outlet鏈接

  4. 如何識別按鈕並執行其對應的方法?有不少方式:能夠每一個按鈕都添加一個action,也能夠只添加一個action,可是給按鈕添加tag值,以識別不一樣的按鈕。好比若只添加一個action,給abs按鈕tag設爲4,而後按下按鈕時,若檢測到tag=4,則執行下面的代碼。

    if (sender.tag == 4) {
           self.inputText.text = [self.calculator abs:self.calculator.input];        
           NSMutableString *tempStr = [NSMutableString stringWithString:self.inputText.text];
           self.calculator.input = tempStr;
           self.calculator.screen = tempStr;
       }
  5. 在按下某個按鈕的時候,就調用它在模型中對應的方法。

體質計算器

  1. 添加界面,拖一個視圖控制器,添加身高體重的輸入域,以獲取用戶的身高體重值用於體質計算

  2. 新建一個UIViewController類,與1中的視圖控制器創建聯繫

  3. 創建相應的model,能夠繼承Calculate類,也可使用類別(category)。這裏使用類別的方法,類別並非新建一個類,只是在原來的類的基礎上擴展一些方法,因此在類別中只能添加方法,不能添加屬性。//這裏主要用的MVC的思想,業務邏輯和視圖分開

    -(NSString *)computeHealthBMI:(NSString *)height weight:(NSString *)weight
       {
           NSMutableString *expression;
           expression = [NSMutableString stringWithString:weight];
           [expression appendString:@"/(("];
           [expression appendString:height];
           [expression appendString:@"/100.0)"];
           [expression appendString:@"*("];
           [expression appendString:height];
           [expression appendString:@"/100.0))="];
           self.input = expression;
           NSLog(@"health compute, input is %@", self.input);
           NSLog(@"health compute, expression is %@", expression);  
           return [NSString stringWithFormat:@"%.2f", [[self ExpressionCalculate:self.input] floatValue]];
       }
  4. 注意最後還添加一個等號的緣由是,我以前寫的Calculate類中的計算方法中,是用等號作符號識別的。

設備鎖屏

設備鎖屏能夠用代碼的方法,不過我折騰了半天沒搞出來,後來直接在general中把它關掉了
設備鎖屏

添加矩形邊框

這主要涉及到在UIView上畫圖了,兩個問題須要解決,怎麼畫一個矩形以及怎麼在一個View上畫圖。

  1. 畫圖方式
    首先,新建一個類繼承UIView類,如drawRectView,要在該類中覆蓋drawRect方法;

而後,在drawRect中畫出矩形;
最後,將畫圖的視圖控制器綁定新建的這個drawRectView。

  1. 畫矩形//代碼是找的別人的,尚未細細研究過,這塊待補2015.1.11補
    畫圖的代碼參考的是斯坦福白鬍子大叔的課裏面的內容,在第七課。大體的意思,先定義了factor,目的是無論咱們的視圖怎麼變化,都能按相同的比例、位置在view上畫圖。self.bounds是你在你本身的視圖用本身的代碼繪製時使用的矩形。具體的下次寫白鬍子大叔的assignment再細說(po主又是一堆死線壓身(╥﹏╥)

#define DEFAULT_FACE_CARD_SCALE_FACTOR 0.90
#define CORNER_FONT_STANDARD_HEIGHT 180.0
#define CORNER_RADIUS 12
  • (CGFloat)cornerScaleFacctor { return self.bounds.size.height / CORNER_FONT_STANDARD_HEIGHT; }

  • (CGFloat)cornerRadius { return CORNER_RADIUS * [self cornerScaleFacctor]; }

  • (CGFloat)cornerOffset { return [self cornerRadius] / 3.0; }

    -(void)drawRect:(CGRect)rect{

    UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:[self cornerRadius]];
    [roundedRect addClip];
    [[UIColor whiteColor] setStroke];   
    [roundedRect stroke];

    }

  • (void)setup
    {

    self.backgroundColor = nil; //don't draw background
    self.opaque = NO;
    self.contentMode = UIViewContentModeRedraw;//bounds change call drawRect

    }

  • (void)awakeFromNib
    {

    [self setup];
    [self setNeedsDisplay];

    }

控制屏幕長度

//我感受個人方式很不優雅...

  1. 屏幕上的輸出是經過按按鈕的操做來改變的,因此應該在touchButton的這個action方法中修改。

  2. 另外,屏幕的輸出是保存在inputText.text中的,可是以前的代碼會用inputText.text來賦值,要控制屏幕的輸出長度的話就要避免用它來賦值。

  3. 最後,用了一個magic number(因此說不優雅嘛),觀察以後發現長度爲13恰好可以不自動縮小(其實這個好像能夠修改textfield的屬性來控制),而後就按此分紅了兩種狀況處理。

    if ([[[sender titleLabel] text] isEqualToString:@"×"]) {

    [self.calculator.input appendString:@"*"];

    }else if([[[sender titleLabel] text] isEqualToString:@"÷"]){

    [self.calculator.input appendString:@"/"];

    }else

    [self.calculator.input appendString:[[sender titleLabel] text]];

    if (self.inputText.text.length == 13) {//將屏幕長度控制在13

    NSMutableString *str = [NSMutableString stringWithString:self.calculator.input];
       NSLog(@"inputtxt=13, str is %@", str);
       self.calculator.screen = str;
       self.inputText.text = [str substringWithRange:NSMakeRange(str.length - 13, 13)];

    }else{//屏幕長度未超出13

    NSMutableString *str = [NSMutableString stringWithString:self.inputText.text];
       [str appendString:[[sender titleLabel] text]];
       NSLog(@"inputtxt<13, str is %@", str);
       self.calculator.screen = str;
       self.inputText.text = str;

    }

效果圖

完整代碼

效果圖

相關文章
相關標籤/搜索