接上一篇基於iOS的簡單計算器(一)皆爲po主iOS課程的實驗內容。git
高級計算器:可以進行一些高級的運算好比三角函數、階乘、對數等。github
體質計算器:獲取用戶的身高體重後,反饋用戶的體質指數。express
多場景切換segmentfault
高級計算器api
體質計算器app
設備鎖屏ide
畫圖:在體質計算器中的輸出結果上添加矩形邊框函數
控制屏幕顯示的字符串的長度spa
場景:在故事板中,場景指單一視圖控制器及視圖3d
場景過渡:在兩個場景之間和管理兩個場景的過渡。
拖動一個ViewController
新建一個UIViewController類SecondViewController,與前面的ViewController創建聯繫
爲了在兩個視圖控制器之間通信,設定的用於高級計算的類的實例應該放在聲明之中//在.m文件中的話是private的
設定一個屬性screen,用於在視圖控制器之間通信
添加導航控制器Navigation Controller,創建導航控制器和已經作好的兩個視圖控制器的聯繫。注意:使用導航控制器作場景過渡,只能選擇push
注意:在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;//僅傳遞了內容 } } }
在兩個視圖控制器中,都要將結果顯示在屏幕中,因此在兩個視圖控制器的viewWillAppear方法中,都要添加以下代碼
self.inputText.text = self.calculator.screen;//從另外一個場景傳遞回來
注意,每次計算以後,既要修改屏幕上輸出的值,也要修改用於傳遞的screen屬性的值
添加一個高級計算的界面
添加一個用於高級計算的Model。因爲能夠用以前寫好的Calculate類,因此新建的類繼承自該類,而後只要再添加一些用於高級計算的方法便可。實現高級計算的方法不少,這裏用的是C語言的math庫中的函數
諸如括號、e、pi之類的按鈕,因爲咱們須要獲取按鈕上的值,來顯示在結果上,因此咱們須要創建outlet鏈接
如何識別按鈕並執行其對應的方法?有不少方式:能夠每一個按鈕都添加一個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; }
在按下某個按鈕的時候,就調用它在模型中對應的方法。
添加界面,拖一個視圖控制器,添加身高體重的輸入域,以獲取用戶的身高體重值用於體質計算
新建一個UIViewController類,與1中的視圖控制器創建聯繫
創建相應的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]]; }
注意最後還添加一個等號的緣由是,我以前寫的Calculate類中的計算方法中,是用等號作符號識別的。
設備鎖屏能夠用代碼的方法,不過我折騰了半天沒搞出來,後來直接在general中把它關掉了
這主要涉及到在UIView上畫圖了,兩個問題須要解決,怎麼畫一個矩形以及怎麼在一個View上畫圖。
畫圖方式
首先,新建一個類繼承UIView類,如drawRectView,要在該類中覆蓋drawRect方法;
而後,在drawRect中畫出矩形;
最後,將畫圖的視圖控制器綁定新建的這個drawRectView。
畫矩形//代碼是找的別人的,尚未細細研究過,這塊待補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];
}
//我感受個人方式很不優雅...
屏幕上的輸出是經過按按鈕的操做來改變的,因此應該在touchButton的這個action方法中修改。
另外,屏幕的輸出是保存在inputText.text中的,可是以前的代碼會用inputText.text來賦值,要控制屏幕的輸出長度的話就要避免用它來賦值。
最後,用了一個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;
}