UIView(2)

UIView(控件)

UIView的創(chuàng)建

  1. alloc init方法創(chuàng)建
  • 通過UIStoryboard加載控件詳見UIStoryboard
  • 通過xib加載控件詳見XIB

UIView的常用屬性

// superview:獲得自己的父控件對象,每個子控件的superview只有一個,該屬性只讀
// 一般用于判斷是否已經(jīng)加入到視圖中同辣,避免重復(fù)添加
if (view.superview) return;

// subviews:獲得自己的所有子控件對象,只讀
NSLog(@"%@",view.subviews);

// 是否可與用戶交互
view.userInteractionEnabled = YES;

// 裁剪超出范圍的控件
view.clipsToBounds = YES;

// 設(shè)置透明度
view.alpha = 1;

// 設(shè)置背景顏色,默認(rèn)是clearColor
view.backgroundColor = [UIColor colorWithRed:1 green:1 blue:0 alpha:0.3];//顏色由三原色組成

UIView的常用方法

// 添加一個子控件view
// 底層實現(xiàn):
    // 1.判斷傳入view之前有沒有父控件
    // 2.如果有,先移除之前父控件
    // 3.再重新添加view
[self.view addSubview:view];

// 從父控件中移除
// 多用于動畫控件完成動畫后移除
[self.view removeFromSuperview];

UIView獲取子控件或其標(biāo)識

  • 開發(fā)中惭载,經(jīng)常需要使用到標(biāo)識來獲取控件或其標(biāo)識旱函,用于控件間的聯(lián)動,這時的可選方案如下:
    • 方案一:通過tag值(不推薦使用)

      1. tag:控件的ID(標(biāo)識)描滔,父控件可以通過tag來找到對應(yīng)的子控件;
      2. tag默認(rèn)值是0
      3. tag值是隨意設(shè)置棒妨,很容易混亂,能不用就不用含长,開發(fā)時間越長券腔,tag值管理會越來越困難
        // 設(shè)置tag值
        view.tag = 10;
        
        // 根據(jù)tag獲取view,沒找到返回nil
        UIView *view = [self.view viewWithTag:10];
        
        // viewWithTag:內(nèi)部的大致實現(xiàn)思路
        - (UIView *)viewWithTag:(NSInteger)tag
        {
            if (self.tag == tag) return self;
        
            for (UIView *subview in self.subviews) {
            // 返回tag標(biāo)識找出對應(yīng)的控件(一般都是子控件)
                return [subview viewWithTag:tag];
            }
        }
        
    • 方案二:通過subviews數(shù)組獲染信ⅰ(不推薦)

      • 不足:一般都是通過控制器的view的subviews獲取子控件或其標(biāo)識纷纫,但該view不僅有我們自己創(chuàng)建的控件,也有系統(tǒng)創(chuàng)建的控件陪腌,不好把握辱魁,容易出錯;另外子元素種類一般不相同烟瞧,不方便管理
        // 獲取某個子控件
        UIView *view = self.view.subviews[0];
        
        // 獲取控件標(biāo)識
        NSInteger index = [self.views indexOfObject:view]
        
    • 方案三:新建數(shù)組,獲取角標(biāo)獲取控件(推薦方案)

      // 新建控件數(shù)組并作為成員屬性
      NSMutableArray *views = [NSMutableArray array];
      self.views = views;
      
      // 將控件添加到控件數(shù)組中
      [self.views addObject:view];
      [self.views addObject:view1];
      [self.views addObject:view2];
      
      // 獲取控件標(biāo)識
      NSInteger index = [self.views indexOfObject:view]
      
      // 獲取控件
      UIView *view = self.views[index];
      

UIViewContentMode屬性(只對UIImageView控件中圖片有效)

  • 帶有scale單詞的:圖片有可能會拉伸(常用)
scale的屬性 拉伸方式(不旋轉(zhuǎn)圖片 保持原寬高比染簇? 備注
UIViewContentModeScaleToFill 不按比例拉伸拉伸圖片至填充整個控件 圖片跟控件同寬同高燕刻;默認(rèn)屬性
UIViewContentModeScaleAspectFill 按比例拉伸圖片,直至圖片拉伸至填充整個控件 圖片一邊與控件相等剖笙,另一邊于控件
UIViewContentModeScaleAspectFit 按比例拉伸圖片,直至圖片任一邊與控件對應(yīng)邊一樣大 圖片一邊與控件相等请唱,另一邊于控件
  • 沒有scale單詞的:圖片絕對不會被拉伸
不含scale的屬性 是否拉伸 在控件中的顯示位置
UIViewContentModeCenter 保持圖片的原尺寸 居中
UIViewContentModeTop 同上 上面
UIViewContentModeBottom 同上 下面
UIViewContentModeLeft 同上 左面
UIViewContentModeRight 同上 右面
UIViewContentModeTopLeft 同上 左上
UIViewContentModeTopRight 同上 右上
UIViewContentModeBottomLeft 同上 左下
UIViewContentModeBottomRight 同上 右下

UIView的封裝(自定義控件)

  1. 自定義控件基礎(chǔ):父子控件
    1. 每個控件都是個容器弥咪,能容納其他控件
    1. 內(nèi)部小控件是大控件的子控件
    2. 大控件是內(nèi)部小控件的父控件
  • 自定義控件的意義
    1. 如果一個view內(nèi)部的子控件比較多,一般會考慮自定義一個view十绑,把它內(nèi)部子控件的創(chuàng)建屏蔽起來聚至,不暴露給外界

      2. 外界可以傳入對應(yīng)的模型數(shù)據(jù)給view,view拿到模型數(shù)據(jù)后給內(nèi)部的子控件設(shè)置對應(yīng)的數(shù)據(jù)
    
  • 步驟:

    1. 新建一個繼承UIView的類
    • 創(chuàng)建并布局子控件(純代碼或者xib方式)
      1. 純代碼方式
        1. 提供類方法及對象方法
        1. 可以重寫init或initWithFrame方法
        2. 重寫init創(chuàng)建時本橙,底層也會調(diào)用initWithFrame方法扳躬,先調(diào)用父類的,再調(diào)用子類自身甚亭;
        2. 在initWithFrame:方法中添加并初始化子控件
        3. 在layoutSubviews方法中布局子控件贷币,布局前必須調(diào)用[super layoutSubviews];

      2. xib方式
        1. 新建一個xib文件(xib的文件名最好跟控件類名一樣)
        1. 添加子控件、設(shè)置子控件屬性
        2. 修改最大的父控件的class為控件類名
        3. 將子控件進行連線
        2. 提供一個類方法及對象方法用于加載xib
        1. 初始化時底層不調(diào)用initWithFrame:方法亏狰,而是調(diào)用`initWithCoder:方法役纹。加載時:
        2. initWithCoder是第一個執(zhí)行的方法
        3. awakeAfterUsingCoder:是第二個執(zhí)行的方法
        3. awakeFromNib是最后執(zhí)行的方法,可在這里初始化控件

    • 提供模型屬性暇唾,重寫模型屬性的set方法
      • 在set方法中給子控件設(shè)置數(shù)據(jù)

漸變式動畫

  1. 頭尾式
    // 開始動畫
    [UIView beginAnimations:nil context:nil];
    
    // 設(shè)置動畫屬性
    // 設(shè)置動畫時間
    [UIView setAnimationDuration:2.0];
    
    /* 需要執(zhí)行動畫的代碼 */
    
    // 提交動畫
    [UIView commitAnimations];
    
  • block式(實質(zhì)是蘋果對頭尾式動畫的封裝)
    // 在1秒內(nèi)執(zhí)行動畫
    [UIView animateWithDuration:1.0 animations:^{
        // 顯示指示版
        self.hudLbl.alpha = 1;//不透明
    
    } completion:^(BOOL finished) {
    
        // 上一個動畫完畢后延遲3秒后促脉,在1秒內(nèi)執(zhí)行下列動畫
        [UIView animateWithDuration:1.0 delay:3.0 options:kNilOptions animations:^{
    
            // 隱藏指示版
            self.hudLbl.alpha = 0;//完全透明
        } completion:nil];
    }];
    

UIView界面跳轉(zhuǎn)

  1. 如果2個控件如果有重疊部分,那么處于上面的那個控件會蓋住下面的策州。上面的控件不是透明或顏色為clearColor瘸味,會擋住下面控件的顯示

  2. 開發(fā)中需要在某些時刻將指定的控件顯示出來,即放在最上面够挂;這時需要界面跳轉(zhuǎn)旁仿。

  • 界面跳轉(zhuǎn)主要的方法有3種:
    1. 用 UINavigationController 把 View B push 進來。
      [self.navigationController pushViewController:nextView animated:YES];
      
    • 用Modal的 presentModalViewController 方法把 View B 蓋在上面下硕。
      [self presentModalViewController:nextView animated:YES];
      
    • 調(diào)整窗口subView中元素的順序丁逝,也可應(yīng)用于當(dāng)前顯示的父控件中,讓其某個子控件顯示出來;
      // AppDelegate.m 類
      // 添加到窗口上
      [self.window addSubview:viewB];
      [self.window addSubview:viewA];
      
      // 調(diào)整控件位置順序梭姓,讓其顯示出來
      [self.window bringSubviewToFront:viewB];
      
  • 界面跳轉(zhuǎn)的本質(zhì)重新調(diào)整窗口subViews中元素的順序霜幼,讓最后一個元素顯示

UIView圓角裁剪和加邊框方式

方案一 :最簡單的

// 最簡單的方式就是設(shè)置每個 View 自帶的 layer 的屬性即可
view.layer.cornerRadius = 8.0f;

// 如果該 View 有子 View,會是這種狀況
view中有view
// 如果需要切掉除了保留部分以外的子 View誉尖,那么需要加上
view.clipsToBounds = YES;
InMrEb2.jpg-web.jpg
// 如果需要邊框罪既,也簡單,加上 layer 的邊框設(shè)置就可以。
view.layer.borderWidth=10.0f;
view.layer.borderColor= [UIColor yellowColor].CGColor;

// 但是如果細(xì)看,會發(fā)現(xiàn)邊框有嚴(yán)重的黑邊问慎,特別是當(dāng) View 背景色比較深的時候
簡單增加邊框的效果圖

方案一總結(jié):
1.1 好處:簡單颈将,哪里需要圓角就在哪里設(shè)置就可以了。
1.2 缺點:這種方式處理的圓角很模糊烘挫,特別是在視圖比較小的時候,質(zhì)量不高柬甥,當(dāng)背景色比較深的時候有邊框有黑邊現(xiàn)象饮六,而且如果使用了 clipToBounds ,則會觸發(fā)離屏渲染(這個一個很大的坑苛蒲,有興趣的話可以詳細(xì)了解下)卤橄,造成很嚴(yán)重的卡頓問題,特別是在 UITableViewCell 的子 View 中這樣使用臂外,掉幀會很嚴(yán)重窟扑。


簡單裁剪的bug

方案二 :設(shè)置 mask layer

// 使用貝賽爾曲線,并根據(jù)其路徑漏健,得到一個「遮罩 layer」嚎货,將其設(shè)置為 View 自帶 layer 的 mask,蓋掉其他部分蔫浆,剩余中間的部分厂抖。也可以達到圓角效果。

- (void)setRoundedCorners {
   UIBezierPath* maskPath = [UIBezierPathbezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:size];

   CAShapeLayer* maskLayer = [CAShapeLayerlayer];
maskLayer.frame = self.bounds;
maskLayer.path = maskPath.CGPath;

   self.layer.mask = maskLayer;
}
   // 將這個 masklayer 加到自帶 layer 上而不是設(shè)置為其 mask克懊,代碼如下:
   /*
   UIBezierPath* maskPath = [UIBezierPath bezierPathWithRoundedRect:v.boundsbyRoundingCorners:UIRectCornerAllCornerscornerRadii:CGSizeMake(halfW, halfW)];

   CAShapeLayer* maskLayer = [CAShapeLayer layer];
   maskLayer.frame = view.bounds;
   maskLayer.fillColor = [UIColor whiteColor].CGColor;
   maskLayer.path = maskPath.CGPath;
   maskLayer.backgroundColor= [UIColor greenColor].CGColor;

   [view.layer addSublayer:maskLayer];
   */
   
   // 效果圖:
   // 一個只有四個角的 layer 蓋到原來的 layer 上忱辅,達到圓角效果。
   // 因為是蓋住四角達到的效果谭溉,所以不用設(shè)置 maskToBounds 也可以去掉子 View 超出中心圓的部分墙懂,但是同樣會觸發(fā)離屏渲染。用的時候應(yīng)當(dāng)小心扮念。
```![z26jAbI.jpg-web.jpg](http://upload-images.jianshu.io/upload_images/1566132-4b043dfcc9ad6d73.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![設(shè)置mask layer圓角效果圖](http://upload-images.jianshu.io/upload_images/1566132-3da6e98933c5125d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


```objc
   // 如果要加上邊框损搬,可以在 self.layer 上加一個圓環(huán) layer 達到邊框效果,代碼如下:

- (void)setRoundedCorners:(UIRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(UIColor*)borderColor cornerSize:(CGSize)size {
   UIBezierPath* maskPath = [UIBezierPathbezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:size];

   CAShapeLayer* maskLayer = [CAShapeLayerlayer];
   maskLayer.fillColor = [UIColorblueColor].CGColor;
   maskLayer.frame = self.bounds;
   maskLayer.path = maskPath.CGPath;

   self.layer.mask = maskLayer;

   if(borderWidth >0) {
       CAShapeLayer*borderLayer = [CAShapeLayerlayer];

       // 用貝賽爾曲線畫線柜与,path 其實是在線的中間巧勤,這樣會被      layer.mask(遮罩層)遮住一半,故在 halfWidth 處新建 path弄匕,剛好產(chǎn)生一個內(nèi)描邊
       CGFloathalfWidth = borderWidth /2.0f;
       CGRectf =CGRectMake(halfWidth,  halfWidth,CGRectGetWidth(self.bounds) - borderWidth,CGRectGetHeight(self.bounds) - borderWidth);

       borderLayer.path = [UIBezierPathbezierPathWithRoundedRect:f byRoundingCorners:corners cornerRadii:size].CGPath;
       borderLayer.fillColor = [UIColorclearColor].CGColor;
       borderLayer.strokeColor = borderColor.CGColor;
       borderLayer.lineWidth = borderWidth;
       borderLayer.frame =         CGRectMake(0,0,CGRectGetWidth(f),CGRectGetHeight(f));
       [self.layer addSublayer:borderLayer];
}
    // 我們會看到這里 borderLayer 的坐標(biāo)很奇怪颅悉,這里解釋一下,如果我們這樣設(shè)置坐標(biāo)迁匠,用以下方式添加 borderLayer剩瓶,會是什么效果呢驹溃?

    UIBezierPath* borderPath= [UIBezierPathbezierPathWithRect:v.bounds];

    CAShapeLayer* borderLayer= [CAShapeLayer layer];
    borderLayer.path =borderPath.CGPath;
    borderLayer.fillColor = [UIColor clearColor].CGColor;
    borderLayer.strokeColor =   [[UIColorblackColor]colorWithAlphaComponent:0.5].CGColor;
    borderLayer.lineWidth =10;
    borderLayer.frame = v.bounds;
    [v.layer addSublayer:borderLayer];
    
    // 效果圖:
    // 效果分析:
    // 邊框剛好騎在了邊界上,如果這時候我們在使用 maskLayer 做圓角延曙,那騎在邊界上的邊框有外面一半將被吃掉豌鹤,只剩下一半,所以要把 borderLayer 往里挪一半的邊框的距離枝缔,避免讓 maskLayer 吃掉外面那部分邊框布疙。
設(shè)置mask layer增加邊框效果圖1
放大后的效果圖:
設(shè)置mask layer增加邊框效果圖2
方案二總結(jié):
1.1 好處:簡單,并且可以使用貝賽爾曲線達到任意形狀的「剪切」愿卸,也可以根據(jù)情況選擇要「切」的角拐辽,比如如果只需要切右上和右下兩個角,那么只需要改一下貝賽爾曲線
   UIBezierPath* maskPath = [UIBezierPathbezierPathWithRoundedRect:view.bounds byRoundingCorners:UIRectCornerTopRight|UIRectCornerBottomRightcornerRadii:CGSizeMake(halfW, halfW)];
1.2 缺點:上一種方式的缺點擦酌,這個方式也都有

方案三 :生成圓角背景圖片方式

   CGFloat w = 200; 
   UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0,0, w, w)]; 
   v.backgroundColor= [UIColor redColor];
   [self.view addSubview:v];
   v.center = self.view.center; 
   
   UIImage *img = [UIImage imageWithColor:v.backgroundColorandSize:v.bounds.size]; 
   img = [img roundedWithBorderWidth:10borderColor:[UIColorgreenColor]]; 
   
   UIImageView *imageView = [[UIImageView alloc] initWithImage:img];
   [v insertSubview:imageViewatIndex:0]; 
   v.backgroundColor= [UIColor clearColor];
   
   // 根據(jù) View 的大小和背景色,生成一張圖片菠劝,生成圖片的方法如下:
   @implementationUIImage(ZQExtension) 
   + (UIImage*)imageWithColor:(UIColor*)color andSize:(CGSize)size { 
   CGRectrect =CGRectMake(0.0f,0.0f, size.width, size.height); 
   
   UIGraphicsBeginImageContextWithOptions(rect.size,NO, [UIScreenmainScreen].scale); 
   
   CGContextRefcontext =UIGraphicsGetCurrentContext();
   
   CGContextSetFillColorWithColor(context, [colorCGColor]);
   
   CGContextFillRect(context, rect); 
   
   UIImage*image =UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); returnimage; 
   } 
   @end
   
   // 再將這張圖片圓角處理赊舶,并加上邊框,最后創(chuàng)建一個 UIImageView赶诊,設(shè)置該 imageView 的 image 為圓角處理后的圖片笼平,并插入 View 的最底層,造成一種圓角處理的假象舔痪。

   // 圓角處理的代碼如下:

@implementationUIImage(ZQExtension)

- (UIImage*)roundedWithBorderWidth:(CGFloat)borderWidth borderColor:(UIColor*)borderColor {

   CGFloatinset =1;
   CGFloatwidth =self.size.width;
   CGFloatheight =self.size.height;
   CGFloatcornerRadius;
   UIBezierPath*maskShape;
   
   if(width > height) {
        cornerRadius = height / 2.0- inset;
       maskShape = [UIBezierPathbezierPathWithRoundedRect:CGRectMake((width-height)/2.0+ inset,0+ inset, height-2*inset, height-2*inset) cornerRadius:cornerRadius];
       
   }else{
       cornerRadius = width / 2.0- inset;
       maskShape = [UIBezierPathbezierPathWithRoundedRect:CGRectMake(0+inset, (height-width)/2.0+inset, width-2*inset, width-2*inset) cornerRadius:cornerRadius];
}

   UIGraphicsBeginImageContextWithOptions(self.size,NO, [UIScreenmainScreen].scale); 
   
   CGContextRefctx =UIGraphicsGetCurrentContext(); 
   
   CGContextSaveGState(ctx); 
   
   CGContextAddPath(ctx, maskShape.CGPath);
   
   CGContextClip(ctx); CGContextTranslateCTM(ctx,0, height); 
   
   CGContextScaleCTM(ctx,1.0,-1.0); 
   
   CGContextDrawImage(ctx,CGRectMake(0,0, width, height),self.CGImage); 
   
   CGContextRestoreGState(ctx);
   
   if(borderWidth >0) { 
       [borderColor setStroke]; 
       
       CGFloathalfWidth = borderWidth /2.0; 
       
       UIBezierPath*border = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(halfWidth, halfWidth,self.size.width - borderWidth ,self.size.width - borderWidth)];
       
       CGContextSetShouldAntialias(ctx,YES);
       
       CGContextSetAllowsAntialiasing(ctx,YES);
       
       CGContextSetLineWidth(ctx, borderWidth);
       
       CGContextAddPath(ctx, border.CGPath);
       
       CGContextStrokePath(ctx); 
   } 
       UIImage*resultingImage =UIGraphicsGetImageFromCurrentImageContext();
       
       UIGraphicsEndImageContext(); 
       
       returnresultingImage; 
       
   } @end
   
   // 效果如下:
   // 這里使用貝賽爾曲線加邊框的坐標(biāo)和第二種方式的類似寓调。
生成圓角背景圖片方式效果圖
方案三 :生成圓角背景圖片方式總結(jié)
3.1 好處:是不會觸發(fā)離屏渲染,生成圖片和圓角都由 CPU 處理锄码,且邊框清晰夺英,沒有黑邊,
3.2 缺點:不能處理子 View滋捶,在四角處的子 View 不會被「切」掉痛悯,畢竟是一個圓角背景造成的圓角假象,對子 View 沒有什么影響力重窟。

方案四 :使用遮罩層(推薦)

    // 這個遮罩層不是上面提遮罩 layer载萌,是一張你想要保留的形狀的一張圖片,比如想要圓角圖片巡扇,可以讓設(shè)計師做一張這樣圖片:

    // 中間透明扭仁,周圍是想要蓋住的形狀,最中看到的是中間留下來的形狀厅翔,這種做法沒有什么性能損耗乖坠,就是需要麻煩設(shè)計師做一張圖。
    
    // 具體的做法見刀闷,也可以跑一下這個 demo 看看怎么對 UITableView 優(yōu)化的瓤帚。 https://github.com/johnil/VVeboTableViewDemo/blob/master/VVeboTableViewDemo/view/VVeboTableViewCell.m#L46
    
    // 設(shè)計師需要做的圖:
遮罩層圖片

五描姚、總結(jié):UIView圓角裁剪和加邊框方式匯總

5.1 在[離屏渲染優(yōu)化][http://www.reibang.com/p/ca51c9d3575b] (建議好好看看篇文章)中,seedante 對各種圓角方案也有總結(jié)對比戈次,最終得到這樣一個結(jié)果:

5.2 任何時候優(yōu)先考慮避免觸發(fā)離屏渲染轩勘,無法避免時優(yōu)化方案有兩種:

5.3 Rasterization:適用于靜態(tài)內(nèi)容的視圖,也就是內(nèi)部結(jié)構(gòu)和內(nèi)容不發(fā)生變化的視圖怯邪,對上面的所有效果而言绊寻,在實現(xiàn)成本以及性能上最均衡的。即使是動態(tài)變化的視圖悬秉,開啟 Rasterization 后能夠有效降低 GPU 的負(fù)荷澄步,不過在動態(tài)視圖里是否啟用還是看 Instruments 的數(shù)據(jù)。

5.4 規(guī)避離屏渲染和泌,用其他手法來模擬效果村缸,混合圖層是個性能最好、耗能最少的通用優(yōu)化方案武氓,尤其對于 rounded corer 和 mask梯皿。

5.5 總的來說,圓角方案需要根據(jù)情況具體選擇用哪種方式县恕。

UIView的layout機制解釋

// ios layout機制相關(guān)方法

- (CGSize)sizeThatFits:(CGSize)size
- (void)sizeToFit
——————-

- (void)layoutSubviews
- (void)layoutIfNeeded
- (void)setNeedsLayout
——————–

- (void)setNeedsDisplay
- (void)drawRect

/*
layoutSubviews在以下情況下會被調(diào)用:

1东羹、init初始化不會觸發(fā)layoutSubviews

   但是是用initWithFrame 進行初始化時,當(dāng)rect的值不為CGRectZero時,也會觸發(fā)

2忠烛、addSubview會觸發(fā)layoutSubviews

3属提、設(shè)置view的Frame會觸發(fā)layoutSubviews,當(dāng)然前提是frame的值設(shè)置前后發(fā)生了變化

4美尸、滾動一個UIScrollView會觸發(fā)layoutSubviews

5冤议、旋轉(zhuǎn)Screen會觸發(fā)父UIView上的layoutSubviews事件

6、改變一個UIView大小的時候也會觸發(fā)父UIView上的layoutSubviews事件

在蘋果的官方文檔中強調(diào):

      You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.

layoutSubviews, 當(dāng)我們在某個類的內(nèi)部調(diào)整子視圖位置時师坎,需要調(diào)用求类。

反過來的意思就是說:如果你想要在外部設(shè)置subviews的位置,就不要重寫屹耐。

刷新子對象布局

-layoutSubviews方法:這個方法尸疆,默認(rèn)沒有做任何事情,需要子類進行重寫
-setNeedsLayout方法: 標(biāo)記為需要重新布局惶岭,異步調(diào)用layoutIfNeeded刷新布局寿弱,不立即刷新,但layoutSubviews一定會被調(diào)用
-layoutIfNeeded方法:如果按灶,有需要刷新的標(biāo)記症革,立即調(diào)用layoutSubviews進行布局(如果沒有標(biāo)記,不會調(diào)用layoutSubviews)

如果要立即刷新鸯旁,要先調(diào)用[view setNeedsLayout]噪矛,把標(biāo)記設(shè)為需要布局量蕊,然后馬上調(diào)用[view layoutIfNeeded],實現(xiàn)布局

在視圖第一次顯示之前艇挨,標(biāo)記總是“需要刷新”的残炮,可以直接調(diào)用[view layoutIfNeeded]

重繪

-drawRect:(CGRect)rect方法:重寫此方法,執(zhí)行重繪任務(wù)
-setNeedsDisplay方法:標(biāo)記為需要重繪缩滨,異步調(diào)用drawRect
-setNeedsDisplayInRect:(CGRect)invalidRect方法:標(biāo)記為需要局部重繪

sizeToFit會自動調(diào)用sizeThatFits方法势就;

sizeToFit不應(yīng)該在子類中被重寫,應(yīng)該重寫sizeThatFits

sizeThatFits傳入的參數(shù)是receiver當(dāng)前的size脉漏,返回一個適合的size

sizeToFit可以被手動直接調(diào)用

sizeToFit和sizeThatFits方法都沒有遞歸苞冯,對subviews也不負(fù)責(zé),只負(fù)責(zé)自己

———————————-

layoutSubviews對subviews重新布局

layoutSubviews方法調(diào)用先于drawRect

setNeedsLayout在receiver標(biāo)上一個需要被重新布局的標(biāo)記侧巨,在系統(tǒng)runloop的下一個周期自動調(diào)用layoutSubviews

layoutIfNeeded方法如其名舅锄,UIKit會判斷該receiver是否需要layout.根據(jù)Apple官方文檔,layoutIfNeeded方法應(yīng)該是這樣的

layoutIfNeeded遍歷的不是superview鏈,應(yīng)該是subviews鏈

drawRect是對receiver的重繪司忱,能獲得context

setNeedDisplay在receiver標(biāo)上一個需要被重新繪圖的標(biāo)記皇忿,在下一個draw周期自動重繪,iphone device的刷新頻率是60hz烘贴,也就是1/60秒后重繪 
*/
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市撮胧,隨后出現(xiàn)的幾起案子桨踪,更是在濱河造成了極大的恐慌,老刑警劉巖芹啥,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锻离,死亡現(xiàn)場離奇詭異,居然都是意外死亡墓怀,警方通過查閱死者的電腦和手機汽纠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來傀履,“玉大人虱朵,你說我怎么就攤上這事〉稣耍” “怎么了碴犬?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長梆暮。 經(jīng)常有香客問我服协,道長,這世上最難降的妖魔是什么啦粹? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任偿荷,我火速辦了婚禮窘游,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘跳纳。我一直安慰自己忍饰,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布棒旗。 她就那樣靜靜地躺著喘批,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铣揉。 梳的紋絲不亂的頭發(fā)上饶深,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音逛拱,去河邊找鬼敌厘。 笑死,一個胖子當(dāng)著我的面吹牛朽合,可吹牛的內(nèi)容都是我干的俱两。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼曹步,長吁一口氣:“原來是場噩夢啊……” “哼宪彩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起讲婚,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤尿孔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后筹麸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體活合,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年物赶,在試婚紗的時候發(fā)現(xiàn)自己被綠了白指。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡酵紫,死狀恐怖告嘲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奖地,我是刑警寧澤状蜗,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站鹉动,受9級特大地震影響轧坎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泽示,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一缸血、第九天 我趴在偏房一處隱蔽的房頂上張望蜜氨。 院中可真熱鬧,春花似錦捎泻、人聲如沸飒炎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽郎汪。三九已至,卻和暖如春闯狱,著一層夾襖步出監(jiān)牢的瞬間煞赢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工哄孤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留照筑,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓瘦陈,卻偏偏與公主長得像凝危,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晨逝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容