第七課:html
一、Viewgit
通常來講,視圖是一個構造塊,表明屏幕上一塊矩形區域,定義了一個座標空間,並在其中繪製及添加觸控事件等。github
①視圖的層級關係性能
一個視圖只能有一個父視圖,能夠有多個子視圖優化
1 - (void)addSubview:(UIView *)aView; // 父視圖添加子視圖 2 - (void)removeFromSuperview; // 子視圖從父視圖移除本身 ui
②UIWindowthis
UIView的頂級視圖:通常狀況下,iOS應用程序中只有一個UIWindow,指當前顯示的屏幕內容。atom
③UIView的初始化spa
a.從storyboard中初始化:awakeFromNib.net
b.代碼初始化:alloc initWithFrame:
- (void)setup { ... } - (void)awakeFromNib { [self setup]; } - (id)initWithFrame:(CGRect)aRect { self = [super initWithFrame:aRect]; [self setup]; return self; }
④與視圖相關的類
a.CGFloat
b.CGPoint:(CGFloat)x,(CGFloat)y
c.CGSize:(CGFloat)width,(CGFloat)height
d.CGRect:(CGPoint)origin,(CGSize)size
⑤座標系統
a.像素與點的概念:每一個View都有一個只讀屬性contentScaleFactor,用以標識一個點包含多少像素
b.座標系統屬性:(CGRect)bounds,(CGPoint)center,(CGRect)frame
對於View B: bounds = ((0,0),(200,250))
frame = ((140,65),(320,320))
center = (300,225)
此處理解視圖能夠在父視圖中旋轉的概念。
⑥視圖的建立
storyboard:drag
code:alloc initWithFrame (直接使用init默認初始化爲frame = CGRectZero)
1 CGRect labelRect = CGRectMake(20, 20, 50, 30); 2 UILabel *label = [[UILabel alloc] initWithFrame:labelRect]; 3 label.text = @」Hello!」; 4 [self.view addSubview:label];
⑦自定義視圖
經過實現- (void)drawRect:(CGRect)aRect; 方法繪製內容,aRect指須要優化繪製的區域,與視圖最終性能有關(此處不做要求)
注意:drawRect:方法不能主動調用,若須要重繪,能夠調用- (void)setNeedsDisplay;或者- (void)setNeedsDisplayInRect:(CGRect)aRect;,系統會在合適的時間調用drawRect:
a.drawRect的實現過程
使用CoreGraphics: *獲取繪製內容的上下文
*建立繪製路徑(UIBezierPath)
*設置繪製屬性(color,font,textures,lineWidth,linecaps)
*描邊(strok),填充(fill)等
b.UIBezierPath的使用
UIBezierPath封裝好了上下文內容(上下文:指繪製的位置,內容等信息)
UIKit調用DrawRect以前會處理好上下文內容,須要獲取當前上下文內容時使用:CGContextRef context = UIGraphicsGetCurrentContext();
UIBezierPath *path = [[UIBezierPath alloc] init];//建立 //繪製路徑 [path moveToPoint:CGPointMake(75, 10)]; [path addLineToPoint:CGPointMake(160, 150)]; [path addLineToPoint:CGPointMake(10, 150]); //閉合路徑 [path closePath]; //設置描邊和填充 [[UIColor greenColor] setFill]; [[UIColor redColor] setStroke]; //描邊和填充 [path fill]; [path stroke];
//其餘用法 path.lineWidth = 2.0;//設置繪製路徑寬度 UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:(CGRect)bounds cornerRadius:(CGFloat)radius];//繪製圓角矩形 //繪製橢圓 UIBezierPath *oval = [UIBezierPath bezierPathWithOvalInRect:(CGRect)bounds]; //剪裁視圖 [roundedRect addClip];//剪裁後的視圖只能在其路徑區域內繪製,超出部分不會繪製
c.透明度相關
*UIColor:屬性alpha(0.0-1.0)
*UIView:(BOOL)opaque(不透明),alpha(0.0-1.0),hidden(隱藏視圖)
區別請看:http://blog.csdn.net/martin_liang/article/details/40739845
d.子視圖與父視圖轉換時上下文內容變化的問題
壓入(push),取出(pop)狀態
- (void)drawGreenCircle:(CGContextRef)ctxt { CGContextSaveGState(ctxt);//保存當前上下文 [[UIColor greenColor] setFill]; // draw my circle CGContextRestoreGState(ctxt);//恢復保存的上下文 } - (void)drawRect:(CGRect)aRect { CGContextRef context = UIGraphicsGetCurrentContext(); [[UIColor redColor] setFill]; // do some stuff [self drawGreenCircle:context]; // do more stuff and expect fill color to be red }
e.繪製文本
使用NSAttributeString
NSAttributedString *text = ...;//建立繪製內容 CGSize textSize = [text size];//獲取文本尺寸大小 [text drawAtPoint:(CGPoint)p];//將文本繪製到指定位置(左上角),或者使用drawInRect也能夠
f.繪製圖片
UIImage *image = [UIImage imageNamed:@「foo.jpg」]; //UIImage *image = [[UIImage alloc] initWithContentsOfFile:(NSString *)fullPath]; //UIImage *image = [[UIImage alloc] initWithData:(NSData *)imageData]; //使用上下文繪製 UIGraphicsBeginImageContext(CGSize); // draw with CGContext functions UIImage *myImage = UIGraphicsGetImageFromCurrentContext(); UIGraphicsEndImageContext(); //標準繪製 [image drawAtPoint:(CGPoint)p]; //[image drawInRect:(CGRect)r]; //[image drawAsPatternInRect:(CGRect)patRect;
g.bounds變化時視圖的重繪
UIView屬性:@property (nonatomic) UIViewContentMode contentMode;
//位置重繪 UIViewContentMode{Left,Right,Top,Right,BottomLeft,BottomRight,TopLeft,TopRight} //縮放重繪 UIViewContentModeScale{ToFill,AspectFill,AspectFit} // bit stretching/shrinking //bounds變化時調用drawRect重繪 UIViewContentModeRedraw // it is quite often that this is what you want
二、手勢識別
步驟:a.建立手勢識別器,添加到視圖
b.實現手勢觸發時的調用方法
①UIGestureRecognizer
抽象超類,全部具體手勢類的父類
②添加手勢控制
- (void)setPannableView:(UIView *)pannableView // maybe this is a setter in a Controller { _pannableView = pannableView; UIPanGestureRecognizer *pangr = [[UIPanGestureRecognizer alloc] initWithTarget:pannableView action:@selector(pan:)];//target也但是視圖控制器,pan爲觸發時的調用方法,由target類實現 [pannableView addGestureRecognizer:pangr];//講手勢添加到視圖 }
③pan手勢的例子
- (CGPoint)translationInView:(UIView *)aView;//觸摸移動的距離 - (CGPoint)velocityInView:(UIView *)aView;//移動速度 - (void)setTranslation:(CGPoint)translation inView:(UIView *)aView;
④抽象超類提供的state屬性
//UIGestureRecognizerStateBegin 連續手勢開始 //UIGestureRecognizerStateChanged 移動 //UIGestureRecognizerStateEnded //UIGestureRecognizerStateCancelled //UIGestureRecognizerStateFailed //UIGestureRecognizerStateRecognized 識別到手勢 //使用舉例 - (void)pan:(UIPanGestureRecognizer *)recognizer { if ((recognizer.state == UIGestureRecognizerStateChanged) || (recognizer.state == UIGestureRecognizerStateEnded)) { CGPoint translation = [recognizer translationInView:self]; // move something in myself (I’m a UIView) by translation.x and translation.y // for example, if I were a graph and my origin was set by an @property called origin self.origin = CGPointMake(self.origin.x+translation.x, self.origin.y+translation.y); [recognizer setTranslation:CGPointZero inView:self];//恢復手勢移動距離,爲下次手勢識別調用初始化  } }
⑤其餘手勢屬性
//UIPinchGestureRecognizer 捏合手勢 @property CGFloat scale; // 縮放比例 @property (readonly) CGFloat velocity; //速度(readonly) UIRotationGestureRecognizer 旋轉手勢 @property CGFloat rotation; // 旋轉弧度 @property (readonly) CGFloat velocity; //速度(readonly) UISwipeGestureRecognizer 滑動手勢 @property UISwipeGestureRecognizerDirection direction; //方向(4) @property NSUInteger numberOfTouchesRequired; // 觸控數量 UITapGestureRecognizer 點擊手勢 @property NSUInteger numberOfTapsRequired; // 點擊次數 @property NSUInteger numberOfTouchesRequired; //觸控數量
三、其餘
#pragma mark - example
編譯器標記,對方法進行分組,結果以下
五、demo
SuperCard:https://github.com/NSLogMeng/Stanford_iOS7_Study/commit/1505f50229e875776c323fcd08d4b80e04cfcff0
課程視頻地址:網易公開課:http://open.163.com/movie/2014/1/2/A/M9H7S9F1H_M9H80ED2A.html
或者iTunes U搜索standford課程