斯坦福大學公開課 iOS應用開發教程學習筆記(第四課) Views 視圖

第四課名稱: Views 視圖


課程開始老師懷念了一會老喬。接着介紹這次的課程分爲兩部分,一部分是Calculator的Demo,一部分是Views.

課程開始到第四課,其實斯坦福的課程裏是有作業的,人家已經做完了第一個作業了,就是完善計算器這個程序,完成一個比較複雜的計算器:


計算器大概要完整這麼多的功能,有興趣的同學可以把這個作業的pdf下載下來自己完成。下載地址:作業1

個人感覺這個計算器比較奇葩的地方是設計了一個Enter鍵。可能是爲了減小程序的難度吧。

Demo的演示包括下面內容:

1、可編程性,添加一些API,作用是返回計算程序!Api要保證程序向上兼容。Brain是操作數和操作符的組合。通過類方法執行這個程序,也就是計算運算結果。

他說的計算程序,就是操作數和操作符的組合,把這個組合裏的操作數和操作符彈棧並做相應的計算。

Api向上兼容就是說他沒有改變Controller,程序一樣能正常運行。

2、演示使用到了id類型、property 、數組的可變和不可變複製、內省、還有遞歸,一下子關聯了這麼多知識。

這位老師還強調,希望大家通過課程和作業,熟悉各個集合類的使用,熟悉Founation框架的使用,甚至熟悉和適應Obj-c。

用到id是,要用內省判斷來包含id使用時不至於崩潰。

3、裏面的描述的api留到作業了,應該就是把計算時的操作數和操作符 組合成字符串,這樣Controller就可以把這些操作顯示到view上。

4、課程提問討論下nil判斷包含的問題,老師說這是編碼藝術的範疇,他喜好更少的代碼,在確定不需nil判斷時,儘量不要添加。我個人認爲還是添加比較好,這樣可以增加代碼的可讀性。這可能和人家大師的區別吧。

演示代碼如下:

brain頭文件:

  1. #import <Foundation/Foundation.h>  
  2.   
  3.   
  4. @interface CalculatorBrain : NSObject  
  5. - (void)pushOperand:(double)operand;  
  6. - (double)performOperation:(NSString *)operation;  
  7. @property (readonly) id program;  
  8.   
  9. + (double)runProgram:(id)program;  
  10. + (NSString *)descriptionOfProgram:(id)promram;  
  11. @end  
brain的實現文件:

  1. #import "CalculatorBrain.h"  
  2.   
  3. @interface CalculatorBrain()  
  4. @property (nonatomic, strong) NSMutableArray *programStack;  
  5. @end  
  6.   
  7. @implementation CalculatorBrain  
  8.   
  9. @synthesize programStack = _programStack;  
  10.   
  11. - (NSMutableArray *)programStack  
  12. {  
  13.     if (_programStack == nil) _programStack = [[NSMutableArray alloc] init];  
  14.     return _programStack;  
  15. }  
  16.   
  17. - (id)program  
  18. {  
  19.     return [self.programStack copy];  
  20. }  
  21.   
  22. + (NSString *)descriptionOfProgram:(id)program  
  23. {  
  24.     return @"Implement this in Homework #2";  
  25. }  
  26.   
  27. - (void)pushOperand:(double)operand  
  28. {  
  29.     [self.programStack addObject:[NSNumber numberWithDouble:operand]];  
  30. }  
  31.   
  32. - (double)performOperation:(NSString *)operation  
  33. {  
  34.     [self.programStack addObject:operation];  
  35.     return [[self class] runProgram:self.program];  
  36. }  
  37.   
  38. + (double)popOperandOffProgramStack:(NSMutableArray *)stack  
  39. {  
  40.     double result = 0;  
  41.       
  42.     id topOfStack = [stack lastObject];  
  43.     if (topOfStack) [stack removeLastObject];  
  44.       
  45.     if ([topOfStack isKindOfClass:[NSNumber class]])  
  46.     {  
  47.         result = [topOfStack doubleValue];  
  48.     }  
  49.     else if ([topOfStack isKindOfClass:[NSString class]])  
  50.     {  
  51.         NSString *operation = topOfStack;  
  52.         if ([operation isEqualToString:@"+"]) {  
  53.             result = [self popOperandOffProgramStack:stack] +  
  54.             [self popOperandOffProgramStack:stack];  
  55.         } else if ([@"*" isEqualToString:operation]) {  
  56.             result = [self popOperandOffProgramStack:stack] *  
  57.             [self popOperandOffProgramStack:stack];  
  58.         } else if ([operation isEqualToString:@"-"]) {  
  59.             double subtrahend = [self popOperandOffProgramStack:stack];  
  60.             result = [self popOperandOffProgramStack:stack] - subtrahend;  
  61.         } else if ([operation isEqualToString:@"/"]) {  
  62.             double divisor = [self popOperandOffProgramStack:stack];  
  63.             if (divisor) result = [self popOperandOffProgramStack:stack] / divisor;  
  64.         }  
  65.     }  
  66.       
  67.     return result;  
  68. }  
  69.   
  70. + (double)runProgram:(id)program  
  71. {  
  72.     NSMutableArray *stack;  
  73.     if ([program isKindOfClass:[NSArray class]]) {  
  74.         stack = [program mutableCopy];  
  75.     }  
  76.     return [self popOperandOffProgramStack:stack];  
  77. }  
  78.   
  79. @end  

runProgram方法運行計算程序。

第二部分,Views

view的內容

這個是全新的課程。

1、View是屏幕上一個矩形的空間

2、View處理兩件事:畫出矩形控件,並處理其中的事件

3、view組織架構:View是層結構的,View只有superView,可以有多個subView。子view的順序和數組中的位置有關係,數字越大,越顯示在後面。

4、UIWindow ,iOS中,UIWindow沒有那麼重要了。交給view,viewcontroller處理。

views 組織架構

可以在通過工具來管理view的組織架構,也可以通過代碼:

-(void)addSubView:(UIView *)aView;

-(void)removeFromSuperview;

需要注意點的是:

通過父view添加子view

通過子view自己移除自己

view的座標系統

單位:

CGFloat ,是個float數字,在obj-c裏就要用這個單位

CGPoint,是個C結構體,CGPoint p = CGPointMake(33.2.22.3); 表示位置。

CGSize, 是個結構體,表示大小。

CGRect :由一個 CGPoint和一個CGSize組成

用來描述view的主要四種類型。

座標:

左上角是座標的原點。

不用關心一個的點有都少像素,系統會自動適配。如果有需要獲取一個點是多少像素,通過這個屬性:@property CGFloat contentScaleFactor。

view有三個屬性和它的位置大小有關:

CGRect bounds 自己內部的繪製空間。

下面兩個屬性是父類用來定位你的view的屬性。

CGRect center 

CGRect frame

爲什麼bounds和frame 不一樣呢?因爲view是可以伸縮,可以旋轉的,看下圖:


創建views

繼承UIView。

通過alloc  init 創建view .例子:

  1. CGRect labelRect = CGRectMake(20, 20, 50, 30);  
  2. UILabel *label = [[UILabel alloc] initWithFrame:labelRect];   
  3. label.text = @”Hello!”;  
  4. [self.view addSubview:label];  

每個controller都有一個頂級的view,其他view都放在這個view上。

什麼時候需要自定義view呢?當需要特殊的圖形,或控制觸摸事件的時候

通常不要繼承內置的控件。

drawRect

怎麼繪圖呢?覆蓋一個方法:-(void)drawRect:(CGRect)aRect;

紅色警告:決不能自己調用drawRect:。系統調用這個方法。如果你需要重繪怎麼辦?發送這兩個消息

  1. - (void)setNeedsDisplay;  
  2. - (void)setNeedsDisplayInRect:(CGRect)aRect;  
繪製開銷很大

如何利用drawRect呢?調用核心圖形框架,它是C的接口,不是面向對象的。

Core Graphics framework的基本概念是,你創建一個環境,然後創建一些軌跡,比如直線和弧線,再設置他們都字體顏色樣式等並描邊或填充到軌跡裏。這就是繪圖的過程。

繪製圖片和文字是主要的,文字和軌跡是一回事,它有很多精細的弧線組成。

繪製圖片是賦值二進制碼。

context(環境) ,決定了你要在哪繪製。

每次drawRect是的環境都是不一樣的,所以不要緩存context。

獲取環境的代碼:

  1. CGContextRef context = UIGraphicsGetCurrentContext();  

幾乎所有的drawRect都把這個放在第一行。

  1. CGContextBeginPath(context);  
  2. CGContextMoveToPoint(context, 75, 10);  
  3. CGContextAddLineToPoint(context, 160, 150);  
  4. CGContextAddLineToPoint(context, 10, 150);  
  5. [[UIColor greenColor] setFill];   
  6. [[UIColor redColor] setStroke];  
  7. CGContextDrawPath(context,kCGPathFillStroke); //kCGPathFillStroke is a constant  
上面代碼:繪製的過程,先開始一個軌跡,移動軌跡的點,添加線,填充綠色,描邊是紅色, 顏色不需要指定context,默認就是當前的context。

調用 CGContextDrawpath在屏幕上畫出來。

可以定義一個軌跡保存,在其他環境重用。
透明:

  1. @property CGFloat alpha  
  2. @property BOOL opaque  
alpha  1,不透明, 0透明。

  1. @property (nonatomic) BOOL hidden;  
隱藏view。

畫文字

用UILabel
用UIFont設置字體 大小
  1. UIFont *myFont = [UIFont systemFontOfSize:12.0];  
  2. UIFont *theFont = [UIFont fontWithName:@“Helvetica” size:36.0];  
  3. NSArray *availableFonts = [UIFont familyNames];  
最後一個獲取可用的字體。
用NSString 來畫文字
  1. NSString *text = ...;  
  2. [text drawAtPoint:(CGPoint)p withFont:theFont]; // NSString instance method  
因爲UIKit,所以NSString也能實現UI上的功能,用了categories .

畫圖像

UIImageView 
通過下面的方式後去圖像:
xcode
  1. UIImage *image = [UIImage imageNamed:@“foo.jpg”];  
二進制,網絡
  1. UIImage *image = [[UIImage alloc] initWithContentsOfFile:(NSString *)fullPath];  
  2. UIImage *image = [[UIImage alloc] initWithData:(NSData *)imageData];  
通過CGContext函數
  1. UIGraphicsBeginImageContext(CGSize);  
  2. // draw with CGContext functions  
  3. UIImage *myImage = UIGraphicsGetImageFromCurrentContext();  
  4. UIGraphicsEndImageContext();  
在環境裏畫出來
  1. [image drawAtPoint:(CGPoint)p];  
  2. [image drawInRect:(CGRect)r];  
  3. [image drawAsPatternInRect:(CGRect)patRect;  
drawAtPoint 會按原大小畫出來
drawInRect會縮放。
drawAsPatternInRect會重複繪製來甜蜜指定的區域。

下節課預告。會講到源碼控制,協議,自定義的UIView ViewController的生命週期。還有storyboard的講解。對應兩個平臺的storyboard的使用。

容芳志 (http://blog.csdn.net/totogo2010)

本文遵循“署名-非商業用途-保持一致”創作公用協議


原文地址:http://blog.csdn.net/totogo2010/article/details/8220943

發佈了27 篇原創文章 · 獲贊 3 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章