<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      IOS的UITableView

      UITableView

      概述

      1 UITableView
      2     一般用來展示表格數據、可以滾動(繼承自UIScrollView).性能極佳
      3 UITableView分兩種樣式:
      4     Plain,不分組的樣式
      5     Grouped,分組的樣式
      6     UITableView默認為Plain樣式,改為Grouped后實現分組,如果再改回Plain 那么在滾動的時候 上一層的頭標簽就會一直作為索引顯示,類似于通訊錄中的A B的顯示方式

      使用:

       1 如果要使用UITableView 那么需要實現UITableViewDataSource協議后重寫 2 
       3 //展現數據有幾組,當不實現這個方法時,默認為一組
       4 -(NSInteger)numberOfSectionsInTableView:(UITableView *) tableView
       5 
       6 //一組有幾行
       7 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section
       8 
       9 //每行顯示什么內容
      10 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
      11 
      12 //實現右側的索引欄
      13 -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
      14 (獲取group數組中的每個對象的title值,并返回到一個NSArray中
      15 [self.groups valueForKeyPath:@"title"])
      16 
      17 //通過代理堅挺cell的點擊事件
      18 //選中某行
      19 -(void)tableView:(UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath
      20 
      21 //取消選中某行
      22 -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;
      23 
        //設置組標題
        -(NSString *)tableView :(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;

        //設置組描述
        -(NSString *)tableView :(UITableView *)tableView titleForFooterInsection:(NSInteger)section;


      24 //修改每行的行高 25 1.如果tableView的行高一樣,那么就在控制器的viewDidLoad中統一設置行高tableView.rowHeight(這種方法比較高效) 26 2.通過代理方法實現: 27 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath(低效)

        //把UITableView中的最后一行的數據滾動到最上面
            NSIndexPath *idxPath = [NSIndexPath indexPathForRow:self.goods.count - 1 inSection:0];
           [self.tableView scrollToRowAtIndexPath:idxPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
       

       UITableView的常見屬性

      1 rowHeight 可以統一設置所有行的高度
      2 
      3 separatorColor 分割線的顏色
      4 separatorStyle 分割線的樣式
      5 
      6 tableHeaderView 一般可以放廣告
      7 tableFooterView  一般可以放加載更多

      Cell的常見屬性

       1 imageView
       2 textLabel
       3 detailTextLabel
       4 
       5 accessoryType
       6 accessoryView
       7 
       8 backgroundColor,設置單元格的背景顏色
       9 
      10 backgroundView 可以利用這個屬性來設置單元格的背景圖片,指定一個UIImageView就可以了
      11 
      12 selectedBackgroundView 當某行被選中的時候的背景

       單元格Cell的重用

      1 //注意:只適用于單元格樣式一致的時候
      2 //單元格重用的基本方法
      3 //1.聲明一個 靜態的重用ID (只所以聲明靜態是為了節省控制器不斷的釋放,創建成員對象)
      4 //2.根據重用ID去緩存池中獲取對應的cell對象
      5 //3.如果沒有獲取到,就創建一個,如果獲取到了就直接設置單元格內容
      6 //4.返回單元格

      注意:當使用自定義的cell的時候 是無法通過 dequeueReusableCellWithIdentifier:ID的方式來指定ID的

      所以需要在布局文件中進行設置

      代碼示例:

      1.  .plist的數據結構

        

       模型代碼:

       1.1)CZGroup.h 

       1 #import <Foundation/Foundation.h>
       2 
       3 @interface GZGroup :NSObject
       4 
       5 @property (nonatomic ,copy) NSString *titile;
       6 @property (nonatomic, strong) NSArray *cars;
       7 
       8 -(instancetype)initWithDict :(NSDictionary *)dict;
       9 +(instancetype)groupWithDict:(NSDictionary *)dict;
      10 
      11 @end

        GZGroup.m

      #import "CZGroup.h"
      #import "CZCar.h"
      @implementation CZGroup
      
      - (instancetype)initWithDict:(NSDictionary *)dict
      {
          if (self = [super init]) {
              //        self.title = dict[@"title"];
              //        self.cars = dict[@"cars"];
      
              [self setValuesForKeysWithDictionary:dict];
              
              // 當有模型嵌套的時候需要手動把字典轉成模型
              // 創建一個用來保存模型的數組
              NSMutableArray *arrayModels = [NSMutableArray array];
              // 手動做一下字典轉模型
              for (NSDictionary *item_dict in dict[@"cars"]) {
                  CZCar *model = [CZCar carWithDict:item_dict];
                  [arrayModels addObject:model];
              }
              self.cars = arrayModels;
          }
          return self;
      }
      + (instancetype)groupWithDict:(NSDictionary *)dict
      {
          return [[self alloc] initWithDict:dict];
      }
      @end

      控制器代碼,重用cell需要這是一個ID

       1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
       2 {
       3     // 1. 獲取模型數據
       4     // 根據組的索引獲取對應的組的模型
       5     CZGroup *group = self.groups[indexPath.section];
       6     // 根據當前行的索引, 獲取對應組的對應行的車
       7     CZCar *car = group.cars[indexPath.row];
       8     
       9     
      10     
      11     // 2. 創建單元格
      12     // 2.1 聲明一個重用ID
      13     static NSString *ID = @"car_cell";
      14     // 2.2 根據重用ID去緩存池中獲取對應的cell對象
      15     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
      16     // 2.3 如果沒有獲取到, 那么就創建一個
      17     if (cell == nil) {
      18         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
      19     }
      20     
      21     // 3. 設置單元格內容
      22     cell.imageView.image = [UIImage imageNamed:car.icon];
      23     cell.textLabel.text = car.name;
      24     
      25     // 4. 返回單元格
      26     return cell;
      27 }

       自定義Cell

      案例一:團購

      Viewontroller.m

        1 #import "ViewController.h"
        2 #import "CZGoods.h"
        3 #import "CZGoodsCell.h"
        4 #import "CZFooterView.h"
        5 #import "CZHeaderView.h"
        6 
        7 @interface ViewController () <UITableViewDataSource, CZFooterViewDelegate>
        8 
        9 // 用來存儲所有的團購商品的數據
       10 @property (nonatomic, strong) NSMutableArray *goods;
       11 
       12 @property (weak, nonatomic) IBOutlet UITableView *tableView;
       13 @end
       14 
       15 @implementation ViewController
       16 
       17 
       18 #pragma mark - 懶加載數據
       19 - (NSMutableArray *)goods
       20 {
       21     if (_goods == nil) {
       22         NSString *path = [[NSBundle mainBundle] pathForResource:@"tgs.plist" ofType:nil];
       23         NSArray *arrayDict = [NSArray arrayWithContentsOfFile:path];
       24         NSMutableArray *arrayModels = [NSMutableArray array];
       25         for (NSDictionary *dict in arrayDict) {
       26             CZGoods *model = [CZGoods goodsWithDict:dict];
       27             [arrayModels addObject:model];
       28         }
       29         _goods = arrayModels;
       30     }
       31     return _goods;
       32 }
       33 
       34 #pragma mark - 數據源方法
         //返回有UITableView 有多少個組,默認為1,當組為1時 可以忽略不寫 35 //- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 36 //{ 37 // return 1; 38 //} 39 40 //返回組內有多少行數據 41 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 42 { 43 return self.goods.count; 44 } 45 46 //返回Cell對象 47 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 48 { 49 // 1. 獲取模型數據 50 CZGoods *model = self.goods[indexPath.row]; 51 52 // 2. 創建單元格 53 // 通過xib的方式來創建單元格 54 CZGoodsCell *cell = [CZGoodsCell goodsCellWithTableView:tableView]; 55 56 57 // 3. 把模型數據設置給單元格 58 // 在控制器中直接為cell的每個子控件賦值數據造成的問題: 59 // 1. 控制器強依賴于Cell, 一旦cell內部的子控件發生了變化, 那么控制器中的代碼也得改(這就造成了緊耦合) 60 // 2. cell的封裝不夠完整, 凡是用到這個cell的地方, 每次都要編寫為cell的子控件依次賦值的語句,比如:cell.xxx = model.title; 61 // 3. 解決: 直接把模型傳遞給自定義Cell, 然后在自定義cell內部解析model中的數據賦值給自定義cell內部的子控件。 62 cell.goods = model; 63 64 // 4.返回單元格 65 return cell; 66 } 67 68 69 70 #pragma mark - 隱藏狀態欄 71 - (BOOL)prefersStatusBarHidden 72 { 73 return YES; 74 } 75 80 - (void)viewDidLoad { 81 [super viewDidLoad]; 82 self.tableView.rowHeight = 44; 83 84 // 設置UITableView的footerView 85 // UIButton *btn = [UIButton buttonWithType:UIButtonTypeContactAdd]; 86 // 87 // btn.backgroundColor = [UIColor redColor]; 88 // btn.frame = CGRectMake(20, 50, 30, 100); 89 // // tableView的footerView的特點: 只能修改x和height的值, Y 和 width不能改。 90 // self.tableView.tableFooterView = btn; 91 92 93 94 // 通過Xib設置UITableView的footerView 95 CZFooterView *footerView = [CZFooterView footerView]; 96 // 設置footerView的代理 97 footerView.delegate = self; 98 self.tableView.tableFooterView = footerView; 99 100 101 // 創建Header View 102 CZHeaderView *headerView = [CZHeaderView headerView]; 103 self.tableView.tableHeaderView = headerView; 104 105 106 107 108 109 } 110 111 #pragma mark - CZFooterView的代理方法 112 113 - (void)footerViewUpdateData:(CZFooterView *)footerView 114 { 115 // 3. 增加一條數據 116 117 118 // 3.1 創建一個模型對象 119 CZGoods *model = [[CZGoods alloc] init]; 120 model.title = @"驢肉火燒"; 121 model.price = @"6.0"; 122 model.buyCount = @"1000"; 123 model.icon = @"37e4761e6ecf56a2d78685df7157f097"; 124 125 // 3.2 把模型對象加到控制器的goods集合當中 126 [self.goods addObject:model]; 127 128 // 4. 刷新UITableView 129 [self.tableView reloadData]; 130 131 // // 局部刷新(只適用于UITableView總行數沒有發生變化的情況) 132 // NSIndexPath *idxPath = [NSIndexPath indexPathForRow:self.goods.count - 1 inSection:0]; 133 // [self.tableView reloadRowsAtIndexPaths:@[idxPath] withRowAnimation:UITableViewRowAnimationLeft]; 134 135 136 // 5. 把UITableView中的最后一行的數據滾動到最上面 137 NSIndexPath *idxPath = [NSIndexPath indexPathForRow:self.goods.count - 1 inSection:0]; 138 [self.tableView scrollToRowAtIndexPath:idxPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 139 } 140 141 - (void)didReceiveMemoryWarning { 142 [super didReceiveMemoryWarning]; 143 // Dispose of any resources that can be recreated. 144 } 145 146 @end

      自定義的CZGoodsCell對象

      CZGoodsCell.h

      //導入 UIKit/UIKit.h 文件
      #import <UIKit/UIKit.h>
      @class CZGoods;
      //繼承 UITableViewCell
      @interface CZGoodsCell : UITableViewCell
      
      @property (nonatomic, strong) CZGoods *goods;
      
      // 封裝一個創建自定義Cell的方法
      + (instancetype)goodsCellWithTableView:(UITableView *)tableView;
      @end

      CZGoodsCell.m

       1 #import "CZGoodsCell.h"
       2 #import "CZGoods.h"
       3 
       4 @interface CZGoodsCell ()
       5 @property (weak, nonatomic) IBOutlet UIImageView *imgViewIcon;
       6 @property (weak, nonatomic) IBOutlet UILabel *lblTitle;
       7 @property (weak, nonatomic) IBOutlet UILabel *lblPrice;
       8 @property (weak, nonatomic) IBOutlet UILabel *lblBuyCount;
       9 
      10 @end
      11 
      12 
      13 @implementation CZGoodsCell
      14 
      15 + (instancetype)goodsCellWithTableView:(UITableView *)tableView
      16 {
      17     static NSString *ID = @"goods_cell";
      18     CZGoodsCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
      19     if (cell == nil) {
      20         cell = [[[NSBundle mainBundle] loadNibNamed:@"CZGoodsCell" owner:nil options:nil] firstObject];
      21     }
      22     return cell;
      23 }
      24 
      25 
      26 - (void)setGoods:(CZGoods *)goods
      27 {
      28     _goods = goods;
      29     // 把模型的數據設置給子控件
      30     self.imgViewIcon.image = [UIImage imageNamed:goods.icon];
      31     self.lblTitle.text = goods.title;
      32     self.lblPrice.text = [NSString stringWithFormat:@"¥ %@", goods.price];
      33     self.lblBuyCount.text = [NSString stringWithFormat:@"%@ 人已購買", goods.buyCount];
      34 }
      35 
      36 - (void)awakeFromNib {
      37     // Initialization code
      38 }
      39 
      40 - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
      41     [super setSelected:selected animated:animated];
      42 
      43     // Configure the view for the selected state
      44 }
      45 
      46 @end

      尾部的加載更多按鈕

      CZFooterView.h

       1 #import <UIKit/UIKit.h>
       2 @class CZFooterView;
       3 
        //設置一個代理對象 4 @protocol CZFooterViewDelegate <NSObject, UIScrollViewDelegate>
        //提示用戶使用這個代理的時候必須實現下面的代理方法 5 @required 6 - (void)footerViewUpdateData:(CZFooterView *)footerView; 7 @end 8 9 @interface CZFooterView : UIView 10 11 + (instancetype)footerView; 12 @property (nonatomic, weak) id<CZFooterViewDelegate> delegate; 13 @end

      CZFooterView.m

       1 #import "CZFooterView.h"
       2 
       3 @interface CZFooterView ()
       4 @property (weak, nonatomic) IBOutlet UIButton *btnLoadMore;
       5 @property (weak, nonatomic) IBOutlet UIView *waitingView;
       6 - (IBAction)btnLoadMoreClick;
       7 @end
       8 
       9 
      10 @implementation CZFooterView
      11 
      12 + (instancetype)footerView
      13 {
      14     CZFooterView *footerView = [[[NSBundle mainBundle] loadNibNamed:@"CZFooterView" owner:nil options:nil] lastObject];
      15     return footerView;
      16 }
      17 
      18 
      19 /**
      20 *  加載更多按鈕的單擊事件
      21 */
      22 - (IBAction)btnLoadMoreClick {
      23     // 1. 隱藏"加載更多"按鈕
      24     self.btnLoadMore.hidden = YES;
      25     
      26     // 2. 顯示"等待指示器"所在的那個UIView
      27     self.waitingView.hidden = NO;
      28     
      29     
      30     
      31     //GCD方法,標示延遲一定的時間后執行,由于我們這里是模擬操作,當點擊按鈕后,數據立刻會刷新,所以為了模擬逼真一些,這里就加了一個延遲操作的方法
      32     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
      33         
      34         // 3. 調用代理方法實現下面的功能
      35         // 調用footerViewUpdateData方法之前, 為了保證調用不出錯, 所以要先判斷一下代理對象是否真的實現了這個方法, 如果實現了這個方法再調用, 否則不調用.
      36         if ([self.delegate respondsToSelector:@selector(footerViewUpdateData:)]) {
      37             // 3. 增加一條數據
      38             // 3.1 創建一個模型對象
      39             // 3.2 把模型對象加到控制器的goods集合當中
      40             // 4. 刷新UITableView
      41             [self.delegate footerViewUpdateData:self];
      42         }
      43         
      44         
      45         // 4. 顯示"加載更多"按鈕
      46         self.btnLoadMore.hidden = NO;
      47         
      48         // 5. 隱藏"等待指示器"所在的那個UIView
      49         self.waitingView.hidden = YES;
      50         
      51     });
      52     
      53     
      54     
      55     
      56     
      57     
      58 }
      59 @end

      案例二:微博

      1):當我們的控制器Controller是 tableView的時候,我們可以直接使用Table View Controller,需要指定dataSource 和 delegate的代理對象

      2):由于微博中的內容信息是不一致的,table欄的寬度也是不一致的,所以我們沒有辦法在 viedieLoad中 使用self.tableview.rowHeight 來設置統一的高度,所以我們針對每一個Cell的Frame做了一個封裝,在懶加載數據時,將數據直接給Frame對象,然后Frame對象根據內容計算出高度,后再Cell的時候 直接返回Cell對象

       

      封裝的Frame對象

      CZWeiboFrame.h

       1 #import <Foundation/Foundation.h>
       2 #import <CoreGraphics/CoreGraphics.h>
       3 #import <UIKit/UIKit.h>
       4 #define nameFont [UIFont systemFontOfSize:12]
       5 #define textFont [UIFont systemFontOfSize:14]
       6 
       7 @class CZWeibo;
       8 @interface CZWeiboFrame : NSObject
       9 
      10 @property (nonatomic, strong) CZWeibo *weibo;
      11 
      12 // 用來保存頭像的frame
      13 @property (nonatomic, assign, readonly) CGRect iconFrame;
      14 
      15 // 昵稱的frame
      16 @property (nonatomic, assign, readonly) CGRect nameFrame;
      17 
      18 
      19 // vip的frame
      20 @property (nonatomic, assign, readonly) CGRect vipFrame;
      21 
      22 // 正文的frame
      23 @property (nonatomic, assign, readonly) CGRect textFrame;
      24 
      25 //配圖的frame
      26 @property (nonatomic, assign, readonly) CGRect picFrame;
      27 
      28 // 行高
      29 @property (nonatomic, assign, readonly) CGFloat rowHeight;
      30 
      31 @end

      CZWeiboFrame.m

       1 #import "CZWeiboFrame.h"
       2 #import "CZWeibo.h"
       3 
       4 @implementation CZWeiboFrame
       5 
       6 // 重寫weibo屬性的set方法
       7 - (void)setWeibo:(CZWeibo *)weibo
       8 {
       9     _weibo = weibo;
      10     
      11     // 計算每個控件的frame, 和行高
      12     
      13     // 提取統一的間距
      14     CGFloat margin = 10;
      15     
      16     // 1. 頭像
      17     CGFloat iconW = 35;
      18     CGFloat iconH = 35;
      19     CGFloat iconX = margin;
      20     CGFloat iconY = margin;
      21     _iconFrame = CGRectMake(iconX, iconY, iconW, iconH);
      22     
      23     
      24     
      25     // 2. 昵稱
      26     // 獲取昵稱字符串
      27     NSString *nickName = weibo.name;
      28     CGFloat nameX = CGRectGetMaxX(_iconFrame) + margin;
      29     
      30     // 根據Label中文字的內容, 來動態計算Label的高和寬
      31     CGSize nameSize = [self sizeWithText:nickName andMaxSize:CGSizeMake(MAXFLOAT, MAXFLOAT) andFont:nameFont];
      32     
      33     CGFloat nameW = nameSize.width;
      34     CGFloat nameH = nameSize.height;
      35     CGFloat nameY = iconY + (iconH - nameH) / 2;
      36     
      37     _nameFrame = CGRectMake(nameX, nameY, nameW, nameH);
      38     
      39     
      40     
      41     // 3. 會員
      42     CGFloat vipW = 10;
      43     CGFloat vipH = 10;
      44     CGFloat vipX = CGRectGetMaxX(_nameFrame) + margin;
      45     CGFloat vipY = nameY;
      46     _vipFrame = CGRectMake(vipX, vipY, vipW, vipH);
      47     
      48     
      49     
      50     // 4. 正文
      51     CGFloat textX = iconX;
      52     CGFloat textY = CGRectGetMaxY(_iconFrame) + margin;
      53     CGSize textSize = [self sizeWithText:weibo.text andMaxSize:CGSizeMake(300, MAXFLOAT) andFont:textFont];
      54     CGFloat textW = textSize.width;
      55     CGFloat textH = textSize.height;
      56     _textFrame = CGRectMake(textX, textY, textW, textH);
      57     
      58     
      59     // 5. 配圖
      60     CGFloat picW = 100;
      61     CGFloat picH = 100;
      62     CGFloat picX = iconX;
      63     CGFloat picY = CGRectGetMaxY(_textFrame) + margin;
      64     _picFrame = CGRectMake(picX, picY, picW, picH);
      65     
      66     
      67     //6. 計算每行的高度
      68     CGFloat rowHeight = 0;
      69     if (self.weibo.picture) {
      70         // 如果有配圖, 那么行高就等于配圖的最大的Y值  + margin
      71         rowHeight = CGRectGetMaxY(_picFrame) + margin;
      72     } else {
      73         // 如果沒有配圖, 那么行高就等于正文的最大的Y值  + margin
      74         rowHeight = CGRectGetMaxY(_textFrame) + margin;
      75     }
      76     
      77     // 注意::: 計算完畢行高以后,不要忘記為屬性賦值。
      78     _rowHeight = rowHeight;
      79     
      80     
      81 }
      82 
      83 // 根據給定的字符串、最大值的size、給定的字體, 來計算文字應該占用的大小
      84 - (CGSize)sizeWithText:(NSString *)text andMaxSize:(CGSize)maxSize andFont:(UIFont *)font
      85 {
      86     NSDictionary *attr = @{NSFontAttributeName : font};
      87     return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attr context:nil].size;
      88 }
      89 @end

      自定義的cell對象

      之前封裝的frame主要用來存儲所需要的對象數據,以及計算各個控件和總的tableView Item的frame 

      而我們在cell中是用來創建我們需要的對象,以及將最終形成的布局文件返回給tableView

      CZWeiboCell.h

      1 #import <UIKit/UIKit.h>
      2 @class CZWeiboFrame;
      3 @interface CZWeiboCell : UITableViewCell
      4 
      5 @property (nonatomic, strong) CZWeiboFrame *weiboFrame;
      6 
      7 + (instancetype)weiboCellWithTableView:(UITableView *)tableView;
      8 @end

      CZWeiboCell.m

        1 #import "CZWeiboCell.h"
        2 #import "CZWeibo.h"
        3 #import "CZWeiboFrame.h"
        4 
        5 
        6 
        7 @interface CZWeiboCell ()
        8 @property (nonatomic, weak) UIImageView *imgViewIcon;
        9 @property (nonatomic, weak) UILabel *lblNickName;
       10 @property (nonatomic, weak) UIImageView *imgViewVip;
       11 @property (nonatomic, weak) UILabel *lblText;
       12 @property (nonatomic, weak) UIImageView *imgViewPicture;
       13 
       14 
       15 @end
       16 
       17 
       18 @implementation CZWeiboCell
       19 
       20 
       21 #pragma mark - 重寫單元格的initWithStyle:方法
       22 
       23 + (instancetype)weiboCellWithTableView:(UITableView *)tableView
       24 {
       25     static NSString *ID = @"weibo_cell";
       26     CZWeiboCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
       27     if (cell == nil) {
       28         cell = [[CZWeiboCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
       29     }
       30     return cell;
       31 }
       32 
       33 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
       34 {
       35     if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
       36         // 創建5個子控件
       37         
       38         // 1. 頭像
       39         UIImageView *imgViewIcon = [[UIImageView alloc] init];
       40         [self.contentView addSubview:imgViewIcon];
       41         self.imgViewIcon = imgViewIcon;
       42         
       43         // 2. 昵稱
       44         UILabel *lblNickName = [[UILabel alloc] init];
       45         // 設置Label的文字大小
       46         lblNickName.font = nameFont;
       47         
       48         [self.contentView addSubview:lblNickName];
       49         self.lblNickName = lblNickName;
       50         
       51         // 3. 會員
       52         UIImageView *imgViewVip = [[UIImageView alloc] init];
       53         imgViewVip.image = [UIImage imageNamed:@"vip"];
       54         [self.contentView addSubview:imgViewVip];
       55         self.imgViewVip = imgViewVip;
       56         
       57         // 4. 正文
       58         UILabel *lblText = [[UILabel alloc] init];
       59         lblText.font = textFont;
       60         // 設置正文的Label可以自動換行
       61         lblText.numberOfLines = 0;
       62         [self.contentView addSubview:lblText];
       63         self.lblText = lblText;
       64         
       65         // 5. 配圖
       66         UIImageView *imgViewPicture = [[UIImageView alloc] init];
       67         [self.contentView addSubview:imgViewPicture];
       68         self.imgViewPicture = imgViewPicture;
       69     }
       70     return self;
       71 }
       72 
       73 
       74 #pragma mark - 重寫weibo屬性的set方法
       75 - (void)setWeiboFrame:(CZWeiboFrame *)weiboFrame
       76 {
       77     _weiboFrame = weiboFrame;
       78     
       79     // 1. 設置當前單元格中的子控件的數據
       80     [self settingData];
       81     
       82     // 2. 設置當前單元格中的子控件的frame
       83     [self settingFrame];
       84 }
       85 
       86 
       87 // 設置數據的方法
       88 - (void)settingData
       89 {
       90     CZWeibo *model = self.weiboFrame.weibo;
       91     // 1. 頭像
       92     self.imgViewIcon.image = [UIImage imageNamed:model.icon];
       93     
       94     // 2. 昵稱
       95     self.lblNickName.text = model.name;
       96     
       97     // 3. 會員
       98     if (model.isVip) {
       99         // 設置顯示會員圖標
      100         self.imgViewVip.hidden = NO;
      101         // 設置昵稱的顏色是紅色
      102         self.lblNickName.textColor = [UIColor redColor];
      103     } else {
      104         // 設置隱藏會員圖標
      105         self.imgViewVip.hidden = YES;
      106         // 設置昵稱的顏色是黑色
      107         self.lblNickName.textColor = [UIColor blackColor];
      108     }
      109     
      110     // 4. 正文
      111     self.lblText.text = model.text;
      112  
      113     
      114     // 5. 配圖
      115     if (model.picture) {
      116         // 有配圖
      117         // 如果model.picture的值是nil, 那么下面這句話執行會報異常
      118         self.imgViewPicture.image = [UIImage imageNamed:model.picture];
      119         // 顯示圖片框
      120         self.imgViewPicture.hidden = NO;
      121     } else {
      122         // 如果沒有配圖, 隱藏圖片框
      123         self.imgViewPicture.hidden = YES;
      124     }
      125 
      126 }
      127 
      128 // 設置frame的方法
      129 - (void)settingFrame
      130 {
      131     // 1. 頭像
      132     
      133     self.imgViewIcon.frame = self.weiboFrame.iconFrame;
      134     
      135     // 2. 昵稱
      136     self.lblNickName.frame = self.weiboFrame.nameFrame;
      137     
      138     // 3. 會員
      139     self.imgViewVip.frame = self.weiboFrame.vipFrame;
      140     
      141     // 4. 正文
      142     
      143     self.lblText.frame = self.weiboFrame.textFrame;
      144     
      145     // 5. 配圖
      146     self.imgViewPicture.frame = self.weiboFrame.picFrame;
      147 }
      148 
      149 - (void)awakeFromNib {
      150     // Initialization code
      151 }
      152 
      153 - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
      154     [super setSelected:selected animated:animated];
      155 
      156     // Configure the view for the selected state
      157 }
      158 
      159 @end

      TableViewController控制器的類

      這個類會把我們需要重寫的方法展現出來,我們只需要對我們用到的方法進行重寫就可以了

        1 #import "CZTableViewController.h"
        2 #import "CZWeibo.h"
        3 #import "CZWeiboCell.h"
        4 #import "CZWeiboFrame.h"
        5 
        6 @interface CZTableViewController ()
        7 
        8 // 現在要求weiboFrames集合中保存的很多個CZWeiboFrame模型,不再是CZWeibo模型了。
        9 @property (nonatomic, strong) NSArray *weiboFrames;
       10 
       11 @end
       12 
       13 @implementation CZTableViewController
       14 
       15 #pragma mark - 懶加載數據
       16 - (NSArray *)weiboFrames
       17 {
       18     if (_weiboFrames == nil) {
       19         NSString *path = [[NSBundle mainBundle] pathForResource:@"weibos.plist" ofType:nil];
       20         
       21         NSArray *arrayDict = [NSArray arrayWithContentsOfFile:path];
       22         
       23         NSMutableArray *arrayModels = [NSMutableArray array];
       24         
       25         for (NSDictionary *dict in arrayDict) {
       26             // 創建一個數據模型
       27             CZWeibo *model = [CZWeibo weiboWithDict:dict];
       28             
       29             // 創建一個frame 模型
       30             // 創建了一個空得frame模型
       31             CZWeiboFrame *modelFrame = [[CZWeiboFrame alloc] init];
       32             
       33             // 把數據模型賦值給了modeFrame模型中的weibo屬性
       34             modelFrame.weibo = model;
       35             
       36             
       37             [arrayModels addObject:modelFrame];
       38         }
       39         _weiboFrames = arrayModels;
       40     }
       41     return _weiboFrames;
       42 }
       43 
       44 
       45 
       46 - (void)viewDidLoad {
       47     [super viewDidLoad];
       48     
       49     // 統一設置行高
       50     //self.tableView.rowHeight = 300;
       51     
       52 //    NSLog(@"%@", self.view);
       53 //    NSLog(@"%@", self.tableView);
       54     
       55     // Uncomment the following line to preserve selection between presentations.
       56     // self.clearsSelectionOnViewWillAppear = NO;
       57     
       58     // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
       59     // self.navigationItem.rightBarButtonItem = self.editButtonItem;
       60 }
       61 
       62 - (void)didReceiveMemoryWarning {
       63     [super didReceiveMemoryWarning];
       64     // Dispose of any resources that can be recreated.
       65 }
       66 
       67 #pragma mark - Table view 數據源方法
       68 
       69 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
       70     return 1;
       71 }
       72 
       73 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
       74     return self.weiboFrames.count;
       75 }
       76 
       77 
       78 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
       79     
       80     
       81     // 1. 獲取模型數據
       82     CZWeiboFrame *model = self.weiboFrames[indexPath.row];
       83     
       84     
       85     // 2. 創建單元格
       86     CZWeiboCell *cell = [CZWeiboCell weiboCellWithTableView:tableView];
       87     
       88     // 3. 設置單元格數據
       89     cell.weiboFrame = model;
       90     
       91     // 4. 返回單元格
       92     return cell;
       93 }
       94 
       95 
       96 
       97 #pragma mark - Table view 代理方法
       98 
       99 // 返回每行的行高的方法,對于這個案例,其中最重要的就是關于如何計算行高
      100 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
      101 {
      102     CZWeiboFrame *weiboFrame = self.weiboFrames[indexPath.row];
      103     return weiboFrame.rowHeight;
      104 }
      105 
      106 
      107 - (BOOL)prefersStatusBarHidden
      108 {
      109     return YES;
      110 }
      111 
      112 
      113 @end

       案例三:做一個類似于QQ聊天的tableView界面

      這個界面有兩個難點:

      1.信息背后的框體 要包裹住消息內容

      2.監聽系統的鍵盤彈出事件,將我們的View 整體向上位移

      問題1:

       1 我們通過 設置 內邊距的形式來進行解決
       2 
       3 btnText.contentEdgeInsets = UIEdgeInsetsMake(15, 20, 15, 20); 
       4 
       5 同時對于圖片我們要選擇平鋪的方式進行拉伸
       6 
       7  // 加載圖片
       8     UIImage *imageNormal = [UIImage imageNamed:imgNor];
       9     UIImage *imageHighlighted = [UIImage imageNamed:imgHighlighted];
      10     
      11     // 用平鋪的方式拉伸圖片
      12     imageNormal = [imageNormal stretchableImageWithLeftCapWidth:imageNormal.size.width * 0.5 topCapHeight:imageNormal.size.height * 0.5];
      13     imageHighlighted = [imageHighlighted stretchableImageWithLeftCapWidth:imageHighlighted.size.width * 0.5 topCapHeight:imageHighlighted.size.height * 0.5];
      14     
      15     // 設置背景圖
      16     [self.btnText setBackgroundImage:imageNormal forState:UIControlStateNormal];
      17     [self.btnText setBackgroundImage:imageHighlighted forState:UIControlStateHighlighted];

      問題二:

       1 - (void)viewDidLoad {
       2     [super viewDidLoad];
       3     // 取消分割線
       4     self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
       5     
       6     // 設置UITableView的背景色
       7     self.tableView.backgroundColor = [UIColor colorWithRed:236 / 255.0 green:236 / 255.0 blue:236 / 255.0 alpha:1.0];
       8     
       9     // 設置UITableView的行不允許被選中
      10     self.tableView.allowsSelection = NO;
      11     
      12     // 設置文本框最左側有一段間距
      13     UIView *leftVw = [[UIView alloc] init];
      14     leftVw.frame = CGRectMake(0, 0, 5, 1);
      15     
      16     // 把leftVw設置給文本框
      17     self.txtInput.leftView = leftVw;
      18     self.txtInput.leftViewMode = UITextFieldViewModeAlways;
      19     
      20     
      21     // 監聽鍵盤的彈出事件
      22     // 1. 創建一個NSNotificationCenter對象。
      23     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
      24     
      25     // 2. 監聽鍵盤的彈出通知
      26     [center addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
      27     
      28 }
      29 
      30 - (void)keyboardWillChangeFrame:(NSNotification *)noteInfo
      31 {
      32 //    NSLog(@"通知名稱: %@", noteInfo.name);
      33 //    
      34 //    NSLog(@"通知的發布者: %@", noteInfo.object);
      35 //    
      36 //    NSLog(@"通知的具體內容: %@", noteInfo.userInfo);
      37     // 1. 獲取當鍵盤顯示完畢或者隱藏完畢后的Y值
      38     CGRect rectEnd = [noteInfo.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
      39     CGFloat keyboardY = rectEnd.origin.y;
      40     
      41     // 用鍵盤的Y值減去屏幕的高度計算出平移的值
      42     // 1. 如果是鍵盤彈出事件, 那么計算出的值就是負的鍵盤的高度
      43     // 2. 如果是鍵盤的隱藏事件, 那么計算出的值就是零, 因為鍵盤在隱藏以后, 鍵盤的Y值就等于屏幕的高度。
      44     CGFloat tranformValue = keyboardY - self.view.frame.size.height;
      45     
      46     [UIView animateWithDuration:0.25 animations:^{
      47         // 讓控制器的View執行一次“平移”
      48         self.view.transform = CGAffineTransformMakeTranslation(0, tranformValue);
      49     }];
      50     
      51     
      52     
      53     // 讓UITableView的最后一行滾動到最上面
      54     NSIndexPath *lastRowIdxPath = [NSIndexPath indexPathForRow:self.messageFrames.count - 1 inSection:0];
      55     [self.tableView scrollToRowAtIndexPath:lastRowIdxPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
      56 }
      57 
      58 
      59 // ***************** 注意: 監聽通知以后一定要在監聽通知的對象的dealloc方法中移除監聽 *************/.
      60 
      61 - (void)dealloc
      62 {
      63     // 移除通知
      64     [[NSNotificationCenter defaultCenter] removeObserver:self];
      65 }

       

       

      整體代碼

      1.做一個NSString的類擴展 用于字體最大的尺寸

      NSString+CZNSStringExt.h

       1 #import <Foundation/Foundation.h>
       2 #import <UIKit/UIKit.h>
       3 @interface NSString (CZNSStringExt)
       4 
       5 // 對象方法
       6 - (CGSize)sizeOfTextWithMaxSize:(CGSize)maxSize font:(UIFont *)font;
       7 
       8 // 類方法
       9 + (CGSize)sizeWithText:(NSString *)text maxSize:(CGSize)maxSize font:(UIFont *)font;
      10 @end

      NSString+CZNSStringExt.m

       1 #import "NSString+CZNSStringExt.h"
       2 
       3 @implementation NSString (CZNSStringExt)
       4 
       5 // 實現對象方法
       6 - (CGSize)sizeOfTextWithMaxSize:(CGSize)maxSize font:(UIFont *)font
       7 {
       8     NSDictionary *attrs = @{NSFontAttributeName : font};
       9     return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;
      10 }
      11 
      12 // 類方法
      13 + (CGSize)sizeWithText:(NSString *)text maxSize:(CGSize)maxSize font:(UIFont *)font
      14 {
      15     return [text sizeOfTextWithMaxSize:maxSize font:font];
      16 }
      17 
      18 @end

      2.控制器對象

      ViewController.m

        1 #import "ViewController.h"
        2 #import "CZMessage.h"
        3 #import "CZMessageFrame.h"
        4 #import "CZMessageCell.h"
        5 
        6 @interface ViewController () <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>
        7 @property (weak, nonatomic) IBOutlet UITableView *tableView;
        8 
        9 // 用來保存所有的消息的frame模型對象
       10 @property (nonatomic, strong) NSMutableArray *messageFrames;
       11 @property (weak, nonatomic) IBOutlet UITextField *txtInput;
       12 
       13 @end
       14 
       15 @implementation ViewController
       16 #pragma mark - /********** 懶加載數據 *********/
       17 - (NSMutableArray *)messageFrames
       18 {
       19     if (_messageFrames == nil) {
       20         NSString *path = [[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil];
       21         NSArray *arrayDict = [NSArray arrayWithContentsOfFile:path];
       22         
       23         NSMutableArray *arrayModels = [NSMutableArray array];
       24         for (NSDictionary *dict in arrayDict) {
       25             // 創建一個數據模型
       26             CZMessage *model = [CZMessage messageWithDict:dict];
       27             
       28             // 獲取上一個數據模型
       29             CZMessage *lastMessage = (CZMessage *)[[arrayModels lastObject] message];
       30             
       31             // 判斷當前模型的“消息發送時間”是否和上一個模型的“消息發送時間”一致, 如果一致做個標記
       32             if ([model.time isEqualToString:lastMessage.time]) {
       33                 model.hideTime = YES;
       34             }
       35             
       36             // 創建一個frame 模型
       37             CZMessageFrame *modelFrame = [[CZMessageFrame alloc] init];
       38             
       39             modelFrame.message = model;
       40             
       41             
       42             // 把frame 模型加到arrayModels
       43             [arrayModels addObject:modelFrame];
       44         }
       45         _messageFrames = arrayModels;
       46     }
       47     return _messageFrames;
       48 }
       49 
       50 
       51 #pragma mark - /********** 文本框的代理方法 *********/
       52 //- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
       53 //{
       54 //    return YES;
       55 //}
       56 
       57 // 當鍵盤上的return鍵被單擊的時候觸發
       58 - (BOOL)textFieldShouldReturn:(UITextField *)textField
       59 {
       60     // 1. 獲取用戶輸入的文本
       61     NSString *text = textField.text;
       62     
       63     // 2. 發送用戶的消息
       64     [self sendMessage:text withType:CZMessageTypeMe];
       65     
       66     // 3. 發送一個系統消息
       67     [self sendMessage:@"不認識!" withType:CZMessageTypeOther];
       68     
       69     // 清空文本框
       70     textField.text = nil;
       71     
       72     return YES;
       73 }
       74 
       75 // 發送消息
       76 - (void)sendMessage:(NSString *)msg withType:(CZMessageType)type
       77 {
       78     // 2. 創建一個數據模型和frame 模型
       79     CZMessage *model = [[CZMessage alloc] init];
       80     
       81     // 獲取當前系統時間
       82     NSDate *nowDate = [NSDate date];
       83     // 創建一個日期時間格式化器
       84     NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
       85     // 設置格式
       86     formatter.dateFormat = @"今天 HH:mm";
       87     // 進行日期時間的格式化
       88     model.time = [formatter stringFromDate:nowDate];
       89     model.type = type;
       90     model.text = msg;
       91     
       92     
       93     
       94     // 根據當前消息的時間和上一條消息的時間, 來設置是否需要隱藏時間Label
       95     CZMessageFrame *lastMessageFrame = [self.messageFrames lastObject];
       96     NSString *lastTime = lastMessageFrame.message.time;
       97     if ([model.time isEqualToString:lastTime]) {
       98         model.hideTime = YES;
       99     }
      100     
      101     //***** 注意: 要先設置數據模型的hideTime屬性, 然后再設置modelFrame.message = model;
      102     // 因為在設置modelFrame.message = model;的時候set方法中, 內部會用到model.hideTime屬性。
      103     
      104     // 創建一個frame 模型
      105     CZMessageFrame *modelFrame = [[CZMessageFrame alloc] init];
      106     modelFrame.message = model;
      107     
      108     
      109     
      110     // 3. 把frame 模型加到集合中
      111     [self.messageFrames addObject:modelFrame];
      112     
      113     
      114     
      115     
      116     // 4. 刷新UITableView的數據
      117     [self.tableView reloadData];
      118     
      119     // 5. 把最后一行滾動到最上面
      120     NSIndexPath *idxPath = [NSIndexPath indexPathForRow:self.messageFrames.count - 1 inSection:0];
      121     [self.tableView scrollToRowAtIndexPath:idxPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
      122 }
      123 
      124 
      125 
      126 #pragma mark - /********** UITableView的代理方法 *********/
      127 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
      128 {
      129     // 把鍵盤叫回去, 思路: 讓控制器所管理的UIView結束編輯
      130     [self.view endEditing:YES];
      131 }
      132 
      133 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
      134 {
      135     NSLog(@"★★★★★★★★★");
      136 }
      137 
      138 
      139 
      140 #pragma mark - /********** 數據源方法 *********/
      141 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
      142 {
      143     return 1;
      144 }
      145 
      146 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
      147 {
      148     return self.messageFrames.count;
      149 }
      150 
      151 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
      152 {
      153     // 1. 獲取模型數據
      154     CZMessageFrame *modelFrame = self.messageFrames[indexPath.row];
      155     
      156     // 2. 創建單元格
      157     
      158     CZMessageCell *cell = [CZMessageCell messageCellWithTableView:tableView];
      159     
      160     // 3. 把模型設置給單元格對象
      161     cell.messageFrame = modelFrame;
      162     
      163     // 4.返回單元格
      164     return cell;
      165 }
      166 
      167 // 返回每一行的行高
      168 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
      169 {
      170     CZMessageFrame *messageFrame = self.messageFrames[indexPath.row];
      171     return messageFrame.rowHeight;
      172 }
      173 
      174 
      175 
      176 #pragma mark - /********** 其他 *********/
      177 - (void)viewDidLoad {
      178     [super viewDidLoad];
      179     // 取消分割線
      180     self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
      181     
      182     // 設置UITableView的背景色
      183     self.tableView.backgroundColor = [UIColor colorWithRed:236 / 255.0 green:236 / 255.0 blue:236 / 255.0 alpha:1.0];
      184     
      185     // 設置UITableView的行不允許被選中
      186     self.tableView.allowsSelection = NO;
      187     
      188     // 設置文本框最左側有一段間距
      189     UIView *leftVw = [[UIView alloc] init];
      190     leftVw.frame = CGRectMake(0, 0, 5, 1);
      191     
      192     // 把leftVw設置給文本框
      193     self.txtInput.leftView = leftVw;
      194     self.txtInput.leftViewMode = UITextFieldViewModeAlways;
      195     
      196     
      197     // 監聽鍵盤的彈出事件
      198     // 1. 創建一個NSNotificationCenter對象。
      199     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
      200     
      201     // 2. 監聽鍵盤的彈出通知
      202     [center addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
      203     
      204 }
      205 
      206 - (void)keyboardWillChangeFrame:(NSNotification *)noteInfo
      207 {
      208 //    NSLog(@"通知名稱: %@", noteInfo.name);
      209 //    
      210 //    NSLog(@"通知的發布者: %@", noteInfo.object);
      211 //    
      212 //    NSLog(@"通知的具體內容: %@", noteInfo.userInfo);
      213     // 1. 獲取當鍵盤顯示完畢或者隱藏完畢后的Y值
      214     CGRect rectEnd = [noteInfo.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
      215     CGFloat keyboardY = rectEnd.origin.y;
      216     
      217     // 用鍵盤的Y值減去屏幕的高度計算出平移的值
      218     // 1. 如果是鍵盤彈出事件, 那么計算出的值就是負的鍵盤的高度
      219     // 2. 如果是鍵盤的隱藏事件, 那么計算出的值就是零, 因為鍵盤在隱藏以后, 鍵盤的Y值就等于屏幕的高度。
      220     CGFloat tranformValue = keyboardY - self.view.frame.size.height;
      221     
      222     [UIView animateWithDuration:0.25 animations:^{
      223         // 讓控制器的View執行一次“平移”
      224         self.view.transform = CGAffineTransformMakeTranslation(0, tranformValue);
      225     }];
      226     
      227     
      228     
      229     // 讓UITableView的最后一行滾動到最上面
      230     NSIndexPath *lastRowIdxPath = [NSIndexPath indexPathForRow:self.messageFrames.count - 1 inSection:0];
      231     [self.tableView scrollToRowAtIndexPath:lastRowIdxPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
      232 }
      233 
      234 
      235 // ***************** 注意: 監聽通知以后一定要在監聽通知的對象的dealloc方法中移除監聽 *************/.
      236 
      237 - (void)dealloc
      238 {
      239     // 移除通知
      240     [[NSNotificationCenter defaultCenter] removeObserver:self];
      241 }
      242 
      243 
      244 - (void)didReceiveMemoryWarning {
      245     [super didReceiveMemoryWarning];
      246     // Dispose of any resources that can be recreated.
      247 }
      248 
      249 - (BOOL)prefersStatusBarHidden
      250 {
      251     return YES;
      252 }
      253 
      254 @end

      3.自定義的cell對象

      CZMessageCell.h

       1 #import <UIKit/UIKit.h>
       2 
       3 @class CZMessageFrame;
       4 @interface CZMessageCell : UITableViewCell
       5 
       6 // 為自定義單元格增加一個frame 模型屬性
       7 @property (nonatomic, strong) CZMessageFrame *messageFrame;
       8 
       9 
      10 // 封裝一個創建自定義Cell的方法
      11 + (instancetype)messageCellWithTableView:(UITableView *)tableView;
      12 
      13 @end

      CZMessageCell.m

        1 #import "CZMessageCell.h"
        2 #import "CZMessage.h"
        3 #import "CZMessageFrame.h"
        4 
        5 @interface CZMessageCell ()
        6 
        7 @property (nonatomic, weak) UILabel *lblTime;
        8 @property (nonatomic, weak) UIImageView *imgViewIcon;
        9 @property (nonatomic, weak) UIButton *btnText;
       10 @end
       11 
       12 
       13 @implementation CZMessageCell
       14 
       15 #pragma mark -  重寫initWithStyle方法
       16 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
       17 {
       18     if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
       19         // 創建子控件
       20         
       21         // 顯示時間的label
       22         UILabel *lblTime = [[UILabel alloc] init];
       23         // 設置文字大小
       24         lblTime.font = [UIFont systemFontOfSize:12];
       25         // 設置文字居中
       26         lblTime.textAlignment = NSTextAlignmentCenter;
       27         [self.contentView addSubview:lblTime];
       28         self.lblTime = lblTime;
       29         
       30         
       31         // 顯示頭像的UIImageView
       32         UIImageView *imgViewIcon = [[UIImageView alloc] init];
       33         [self.contentView addSubview:imgViewIcon];
       34         self.imgViewIcon = imgViewIcon;
       35         
       36         
       37         // 顯示正文的按鈕
       38         UIButton *btnText = [[UIButton alloc] init];
       39         // 設置正文的字體大小
       40         btnText.titleLabel.font = textFont;
       41         // 修改按鈕的正文文字顏色
       42         [btnText setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
       43         // 設置按鈕中的label的文字可以換行
       44         btnText.titleLabel.numberOfLines = 0;
       45         // 設置按鈕的背景色
       46         //btnText.backgroundColor = [UIColor purpleColor];
       47         
       48         // 設置按鈕中的titleLabel的背景色
       49         //btnText.titleLabel.backgroundColor = [UIColor greenColor];
       50         
       51         // 設置按鈕的內邊距
       52         btnText.contentEdgeInsets = UIEdgeInsetsMake(15, 20, 15, 20);
       53         
       54         [self.contentView addSubview:btnText];
       55         self.btnText = btnText;
       56     }
       57     
       58     // 設置單元格的背景色為clearColor
       59     self.backgroundColor = [UIColor clearColor];
       60     return self;
       61 }
       62 
       63 
       64 #pragma mark -  重寫frame 模型的set方法
       65 - (void)setMessageFrame:(CZMessageFrame *)messageFrame
       66 {
       67     _messageFrame = messageFrame;
       68     
       69     // 獲取數據模型
       70     CZMessage *message = messageFrame.message;
       71     
       72     // 分別設置每個子控件的數據 和 frame
       73     
       74     // 設置 "時間Label"的數據 和 frame
       75     self.lblTime.text = message.time;
       76     self.lblTime.frame = messageFrame.timeFrame;
       77     self.lblTime.hidden = message.hideTime;
       78     
       79     
       80     
       81     // 設置 頭像
       82     // 根據消息類型, 判斷應該使用哪張圖片
       83     NSString *iconImg = message.type == CZMessageTypeMe ? @"me" : @"other";
       84     self.imgViewIcon.image = [UIImage imageNamed:iconImg];
       85     self.imgViewIcon.frame = messageFrame.iconFrame;
       86     
       87     
       88     // 設置消息正文
       89     [self.btnText setTitle:message.text forState:UIControlStateNormal];
       90     self.btnText.frame = messageFrame.textFrame;
       91     
       92     
       93     // 設置正文的背景圖
       94     NSString *imgNor, *imgHighlighted;
       95     if (message.type == CZMessageTypeMe) {
       96         // 自己發的消息
       97         imgNor = @"chat_send_nor";
       98         imgHighlighted = @"chat_send_press_pic";
       99         
      100         // 設置消息的正文文字顏色為 "白色"
      101         [self.btnText setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
      102     } else {
      103         // 對方發的消息
      104         imgNor = @"chat_recive_nor";
      105         imgHighlighted = @"chat_recive_press_pic";
      106         
      107        // 設置消息的正文文字顏色為 "黑色"
      108         [self.btnText setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
      109     }
      110     
      111     // 加載圖片
      112     UIImage *imageNormal = [UIImage imageNamed:imgNor];
      113     UIImage *imageHighlighted = [UIImage imageNamed:imgHighlighted];
      114     
      115     // 用平鋪的方式拉伸圖片
      116     imageNormal = [imageNormal stretchableImageWithLeftCapWidth:imageNormal.size.width * 0.5 topCapHeight:imageNormal.size.height * 0.5];
      117     imageHighlighted = [imageHighlighted stretchableImageWithLeftCapWidth:imageHighlighted.size.width * 0.5 topCapHeight:imageHighlighted.size.height * 0.5];
      118     
      119     // 設置背景圖
      120     [self.btnText setBackgroundImage:imageNormal forState:UIControlStateNormal];
      121     [self.btnText setBackgroundImage:imageHighlighted forState:UIControlStateHighlighted];
      122 }
      123 
      124 
      125 #pragma mark -  創建自定義Cell的方法
      126 + (instancetype)messageCellWithTableView:(UITableView *)tableView
      127 {
      128     static NSString *ID = @"message_cell";
      129     CZMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
      130     if (cell == nil) {
      131         cell = [[CZMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
      132     }
      133     return cell;
      134 }
      135 
      136 - (void)awakeFromNib {
      137     // Initialization code
      138 }
      139 
      140 - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
      141     [super setSelected:selected animated:animated];
      142 
      143     // Configure the view for the selected state
      144 }
      145 
      146 @end

      4.消息模型

      CZMessage.h

       1 #import <Foundation/Foundation.h>
       2 
       3 typedef enum {
       4     CZMessageTypeMe = 0,    // 表示自己
       5     CZMessageTypeOther = 1  // 表示對方
       6 } CZMessageType;
       7 
       8 
       9 @interface CZMessage : NSObject
      10 
      11 // 消息正文
      12 @property (nonatomic, copy) NSString *text;
      13 
      14 // 消息發送時間
      15 @property (nonatomic, copy) NSString *time;
      16 
      17 // 消息的類型(表示是對方發送的消息還是自己發送的消息)
      18 @property (nonatomic, assign) CZMessageType type;
      19 
      20 // 用來記錄是否需要顯示"時間Label"
      21 @property (nonatomic, assign) BOOL hideTime;
      22 
      23 
      24 
      25 - (instancetype)initWithDict:(NSDictionary *)dict;
      26 + (instancetype)messageWithDict:(NSDictionary *)dict;
      27 
      28 @end

      CZMeesge.m

       1 #import "CZMessage.h"
       2 
       3 @implementation CZMessage
       4 
       5 - (instancetype)initWithDict:(NSDictionary *)dict
       6 {
       7     if (self = [super init]) {
       8         [self setValuesForKeysWithDictionary:dict];
       9     }
      10     return self;
      11 }
      12 
      13 + (instancetype)messageWithDict:(NSDictionary *)dict
      14 {
      15     return [[self alloc] initWithDict:dict];
      16 }
      17 @end

      5.展示信息的frame

      CZMessageFram.h

       1 #import <Foundation/Foundation.h>
       2 #import <CoreGraphics/CoreGraphics.h>
       3 #define textFont [UIFont systemFontOfSize:13]
       4 
       5 @class CZMessage;
       6 @interface CZMessageFrame : NSObject
       7 
       8 // 引用數據模型
       9 @property (nonatomic, strong) CZMessage *message;
      10 
      11 // 時間Label的frame
      12 @property (nonatomic, assign, readonly) CGRect timeFrame;
      13 
      14 // 頭像的frame
      15 @property (nonatomic, assign, readonly) CGRect iconFrame;
      16 
      17 // 正文的frame
      18 @property (nonatomic, assign, readonly) CGRect textFrame;
      19 
      20 // 行高
      21 @property (nonatomic, assign, readonly) CGFloat rowHeight;
      22 
      23 @end

      CZMessageFrame.m

       1 #import "CZMessageFrame.h"
       2 #import <UIKit/UIKit.h>
       3 #import "CZMessage.h"
       4 #import "NSString+CZNSStringExt.h"
       5 
       6 @implementation CZMessageFrame
       7 
       8 - (void)setMessage:(CZMessage *)message
       9 {
      10     _message = message;
      11     
      12     // 計算每個控件的frame 和 行高
      13     // 獲取屏幕寬度
      14     CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
      15     // 設置一個統一的間距
      16     CGFloat margin = 5;
      17     
      18     // 計算時間label的frame
      19     CGFloat timeX = 0;
      20     CGFloat timeY = 0;
      21     CGFloat timeW = screenW;
      22     CGFloat timeH = 15;
      23     if (!message.hideTime) {
      24         // 如果需要顯示時間label, 那么再計算時間label的frame
      25         _timeFrame = CGRectMake(timeX, timeY, timeW, timeH);
      26     }
      27     
      28     
      29     
      30     // 計算頭像的frame
      31     CGFloat iconW = 30;
      32     CGFloat iconH = 30;
      33     CGFloat iconY = CGRectGetMaxY(_timeFrame) + margin;
      34     CGFloat iconX = message.type == CZMessageTypeOther ? margin : screenW - margin - iconW;
      35     _iconFrame = CGRectMake(iconX, iconY, iconW, iconH);
      36     
      37     
      38 
      39     // 計算消息正文的frame
      40     // 1. 先計算正文的大小
      41     CGSize textSize = [message.text sizeOfTextWithMaxSize:CGSizeMake(200, MAXFLOAT) font:textFont];
      42     CGFloat textW = textSize.width + 40;
      43     CGFloat textH = textSize.height + 30;
      44     // 2. 再計算x,y
      45     CGFloat textY = iconY;
      46     CGFloat textX = message.type == CZMessageTypeOther ? CGRectGetMaxX(_iconFrame) : (screenW - margin - iconW - textW);
      47     _textFrame = CGRectMake(textX, textY, textW, textH);
      48     
      49     
      50     
      51     // 計算行高
      52     // 獲取 頭像的最大的Y值和正文的最大的Y值, 然后用最大的Y值+ margin
      53     CGFloat maxY = MAX(CGRectGetMaxY(_textFrame), CGRectGetMaxY(_iconFrame));
      54     _rowHeight = maxY + margin;
      55     
      56 }
      57 @end

      方案四,好友列表

      幾個要注意的:

      1.組上得圖標旋轉后變形

      2.cell重用的問題

      這里直接繼承的TableViewController控制器 直接上代碼了

      CZQQFriendsTableViewController.m

        1 #import "CZQQFriendsTableViewController.h"
        2 #import "CZGroup.h"
        3 #import "CZFriend.h"
        4 #import "CZFriendCell.h"
        5 #import "CZGroupHeaderView.h"
        6 
        7 @interface CZQQFriendsTableViewController () <CZGroupHeaderViewDelegate>
        8 
        9 // 保存所有的朋友信息(分組信息)
       10 @property (nonatomic, strong) NSArray *groups;
       11 @end
       12 
       13 @implementation CZQQFriendsTableViewController
       14 
       15 #pragma mark - *********** 懶加載 ***********
       16 - (NSArray *)groups
       17 {
       18     if (_groups == nil) {
       19         NSString *path = [[NSBundle mainBundle] pathForResource:@"friends.plist" ofType:nil];
       20         NSArray *arrayDicts = [NSArray arrayWithContentsOfFile:path];
       21         
       22         NSMutableArray *arrayModels = [NSMutableArray array];
       23         for (NSDictionary *dict in arrayDicts) {
       24             CZGroup *model = [CZGroup groupWithDict:dict];
       25             [arrayModels addObject:model];
       26         }
       27         _groups = arrayModels;
       28         
       29     }
       30     return _groups;
       31 }
       32 
       33 
       34 #pragma mark - *********** CZGroupHeaderViewDelegate的代理方法 ***********
       35 - (void)groupHeaderViewDidClickTitleButton:(CZGroupHeaderView *)groupHeaderView
       36 {
       37     // 刷新table view
       38     //[self.tableView reloadData];
       39     
       40     // 局部刷新(只刷新某個組)
       41     // 創建一個用來表示某個組的對象
       42     NSIndexSet *idxSet = [NSIndexSet indexSetWithIndex:groupHeaderView.tag];
       43     [self.tableView reloadSections:idxSet withRowAnimation:UITableViewRowAnimationFade];
       44 }
       45 
       46 
       47 
       48 
       49 
       50 #pragma mark - *********** 實現數據源方法 ***********
       51 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
       52 {
       53     return self.groups.count;
       54 }
       55 
       56 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
       57 {
       58     // 因為在這個方法中, 要根據當前組的狀態(是否是展開), 來設置不同的返回值
       59     // 所以, 需要為CZGroup模型增加一個用來保存"是否展開"狀態的屬性
       60     CZGroup *group = self.groups[section];
       61     if (group.isVisible) {
       62         return group.friends.count;
       63     } else {
       64         return 0;
       65     }
       66     
       67 }
       68 
       69 // 返回每行的單元格
       70 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
       71 {
       72     // 1. 獲取模型對象(數據)
       73     CZGroup *group = self.groups[indexPath.section];
       74     CZFriend *friend = group.friends[indexPath.row];
       75     
       76     // 2. 創建單元格(視圖)
       77     CZFriendCell *cell = [CZFriendCell friendCellWithTableView:tableView];
       78     
       79     // 3. 設置單元格數據(把模型設置給單元格)
       80     cell.friendModel = friend;
       81     
       82     // 4. 返回單元格
       83     return cell;
       84 }
       85 
       86 
       87 //// 設置每一組的組標題(下面的這個方法只能設置每一組的組標題字符串, 但是我們要的是每一組中還包含其他子控件)
       88 //- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
       89 //{
       90 //    CZGroup *group = self.groups[section];
       91 //    return group.name;
       92 //}
       93 
       94 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
       95 {
       96     // 不要在這個方法中直接創建一個UIView對象返回, 因為這樣無法實現重用該UIView
       97     // 為了能重用每個Header中的UIView, 所以這里要返回一個UITableViewHeaderFooterView
       98     // 1. 獲取模型數據
       99     CZGroup *group = self.groups[section];
      100     
      101     
      102     // 2. 創建UITableViewHeaderFooterView
      103     CZGroupHeaderView *headerVw = [CZGroupHeaderView groupHeaderViewWithTableView:tableView];
      104     headerVw.tag = section;
      105     
      106     // 3. 設置數據
      107     headerVw.group = group;
      108     
      109     // 設置headerView的代理為當前控制器
      110     headerVw.delegate = self;
      111     
      112     
      113     // 在剛剛創建好的header view中獲取的header view的frame都是0, 因為剛剛創建好的header view我們沒有為其frame賦值, 所以frame都是 0
      114     // 但是, 程序運行起來以后, 我們看到的header view是有frame的。原因是: 在當前方法當中, 將header view返回以后, UITableView在執行的時候, 會用到header view, UITableView既然要用Header View, 那么就必須將header view添加到UITableview中, 當把header view添加到UITableView中的時候, UITableView內部會根據一些設置來動態的為header view的frame賦值,也就是說在UITableView即將使用header view的時候, 才會為header view的frame賦值。
      115     
      116     // 4. 返回view
      117     return headerVw;
      118     
      119     
      120 }
      121 
      122 
      123 
      124 
      125 #pragma mark - *********** 隱藏狀態欄 ***********
      126 - (BOOL)prefersStatusBarHidden
      127 {
      128     return YES;
      129 }
      130 
      131 
      132 #pragma mark - *********** 控制器的viewDidLoad方法 ***********
      133 - (void)viewDidLoad
      134 {
      135     [super viewDidLoad];
      136     
      137     // 統一設置每組的組標題的高度
      138     self.tableView.sectionHeaderHeight = 44;
      139 }
      140 
      141 @end

      cell模型對象

      CZFriendCell.h

      1 #import <UIKit/UIKit.h>
      2 @class CZFriend;
      3 @interface CZFriendCell : UITableViewCell
      4 
      5 + (instancetype)friendCellWithTableView:(UITableView *)tableView;
      6 
      7 @property (nonatomic, strong) CZFriend *friendModel;
      8 @end

      CZFriendCell.m

       1 #import "CZFriendCell.h"
       2 #import "CZFriend.h"
       3 
       4 @implementation CZFriendCell
       5 
       6 
       7 + (instancetype)friendCellWithTableView:(UITableView *)tableView
       8 {
       9     static NSString *ID = @"friend_cell";
      10     CZFriendCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
      11     if (cell == nil) {
      12         cell = [[CZFriendCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
      13     }
      14     return cell;
      15 }
      16 
      17 
      18 - (void)setFriendModel:(CZFriend *)friendModel
      19 {
      20     _friendModel = friendModel;
      21     
      22     // 把模型中的數據設置給單元格的子控件
      23     self.imageView.image = [UIImage imageNamed:friendModel.icon];
      24     self.textLabel.text = friendModel.name;
      25     self.detailTextLabel.text = friendModel.intro;
      26     
      27     // 根據當前的好友是不是vip來決定是否要將"昵稱"顯示為紅色
      28     self.textLabel.textColor = friendModel.isVip ? [UIColor redColor] : [UIColor blackColor];
      29 }
      30 
      31 
      32 - (void)awakeFromNib {
      33     // Initialization code
      34 }
      35 
      36 - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
      37     [super setSelected:selected animated:animated];
      38 
      39     // Configure the view for the selected state
      40 }
      41 
      42 @end

      CZGroupHeaderView.h

       1 #import <UIKit/UIKit.h>
       2 @class CZGroupHeaderView;
       3 @protocol CZGroupHeaderViewDelegate <NSObject>
       4 
       5 - (void)groupHeaderViewDidClickTitleButton:(CZGroupHeaderView *)groupHeaderView;
       6 
       7 @end
       8 
       9 
      10 @class CZGroup;
      11 @interface CZGroupHeaderView : UITableViewHeaderFooterView
      12 
      13 @property (nonatomic, strong) CZGroup *group;
      14 
      15 + (instancetype)groupHeaderViewWithTableView:(UITableView *)tableView;
      16 
      17 // 增加一個代理屬性
      18 @property (nonatomic, weak) id<CZGroupHeaderViewDelegate> delegate;
      19 
      20 @end

      CZGroupHeaderView.m

        1 #import "CZGroupHeaderView.h"
        2 #import "CZGroup.h"
        3 
        4 @interface CZGroupHeaderView ()
        5 
        6 @property (nonatomic, weak) UIButton *btnGroupTitle;
        7 
        8 @property (nonatomic, weak) UILabel *lblCount;
        9 
       10 @end
       11 
       12 
       13 @implementation CZGroupHeaderView
       14 
       15 
       16 // 封裝一個類方法來創建一個header view
       17 + (instancetype)groupHeaderViewWithTableView:(UITableView *)tableView
       18 {
       19     static NSString *ID = @"group_header_view";
       20     CZGroupHeaderView *headerVw = [tableView dequeueReusableHeaderFooterViewWithIdentifier:ID];
       21     if (headerVw == nil) {
       22         headerVw = [[CZGroupHeaderView alloc] initWithReuseIdentifier:ID];
       23     }
       24     return headerVw;
       25 }
       26 
       27 // 重寫initWithReuseIdentifier方法, 在創建headerView的時候, 同時創建子控件
       28 - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
       29 {
       30     if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
       31         // 創建按鈕
       32         UIButton *btnGroupTitle = [[UIButton alloc] init];
       33         // 設置按鈕的圖片(三角圖片)
       34         [btnGroupTitle setImage:[UIImage imageNamed:@"buddy_header_arrow"] forState:UIControlStateNormal];
       35         // 設置按鈕的文字顏色
       36         [btnGroupTitle setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
       37         // 設置按鈕默認的背景圖片和高亮時的背景圖片
       38         [btnGroupTitle setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg"] forState:UIControlStateNormal];
       39         // 設置按鈕高亮的背景圖片和高亮時的背景圖片
       40         [btnGroupTitle setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted];
       41         // 設置按鈕中內容整體左對齊
       42         btnGroupTitle.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
       43         // 設置按鈕的內容的內邊距
       44         btnGroupTitle.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
       45         // 設置按鈕標題距離左邊的邊距
       46         btnGroupTitle.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 0);
       47         
       48         // 為按鈕增加一個點擊事件
       49         [btnGroupTitle addTarget:self action:@selector(btnGroupTitleClicked) forControlEvents:UIControlEventTouchUpInside];
       50         
       51         // 設置按鈕中圖片的現實模式
       52         btnGroupTitle.imageView.contentMode = UIViewContentModeCenter;
       53         // 設置圖片框超出的部分不要截掉
       54         btnGroupTitle.imageView.clipsToBounds = NO;
       55         
       56         [self.contentView addSubview:btnGroupTitle];
       57         self.btnGroupTitle = btnGroupTitle;
       58         
       59         // 創建lable
       60         UILabel *lblCount = [[UILabel alloc] init];
       61         [self.contentView addSubview:lblCount];
       62         self.lblCount = lblCount;
       63     }
       64     return self;
       65 }
       66 
       67 
       68 // 組標題按鈕的點擊事件
       69 - (void)btnGroupTitleClicked
       70 {
       71     // 1. 設置組的狀態
       72     self.group.visible = !self.group.isVisible;
       73     
       74 //    // 2.刷新tableView
       75     // 通過代理來實現
       76     if ([self.delegate respondsToSelector:@selector(groupHeaderViewDidClickTitleButton:)]) {
       77         // 調用代理方法
       78         [self.delegate groupHeaderViewDidClickTitleButton:self];
       79     }
       80     
       81    
       82 }
       83 
       84 // 當一個新的header view 已經加到某個父控件中的時候執行這個方法。
       85 - (void)didMoveToSuperview
       86 {
       87     if (self.group.isVisible) {
       88         // 3. 讓按鈕中的圖片實現旋轉
       89         self.btnGroupTitle.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
       90     } else {
       91         self.btnGroupTitle.imageView.transform = CGAffineTransformMakeRotation(0);
       92     }
       93 }
       94 
       95 // 重寫group屬性的set方法
       96 - (void)setGroup:(CZGroup *)group
       97 {
       98     _group = group;
       99     // 設置數據
      100     
      101     // 設置按鈕上的文字
      102     [self.btnGroupTitle setTitle:group.name forState:UIControlStateNormal];
      103     // 設置 lblCount商的文字
      104     self.lblCount.text = [NSString stringWithFormat:@"%d / %d", group.online, group.friends.count];
      105     
      106     // 設置按鈕中的圖片旋轉問題
      107     if (self.group.isVisible) {
      108         // 3. 讓按鈕中的圖片實現旋轉
      109         self.btnGroupTitle.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
      110     } else {
      111         self.btnGroupTitle.imageView.transform = CGAffineTransformMakeRotation(0);
      112     }
      113     
      114     
      115     // 設置frame不要寫在這里, 因為在這里獲取的當前控件(self)的寬和高都是0
      116     
      117     
      118    
      119 }
      120 
      121 // 當當前控件的frame發生改變的時候會調用這個方法
      122 - (void)layoutSubviews
      123 {
      124     [super layoutSubviews];
      125     
      126     // 設置按鈕的frame
      127     self.btnGroupTitle.frame = self.bounds;
      128     //NSLog(@"%@", NSStringFromCGRect(self.btnGroupTitle.frame));
      129     
      130     // 設置lable的frame
      131     CGFloat lblW = 100;
      132     CGFloat lblH = self.bounds.size.height;
      133     CGFloat lblX = self.bounds.size.width - 10 - lblW;
      134     CGFloat lblY = 0;
      135     self.lblCount.frame = CGRectMake(lblX, lblY, lblW, lblH);
      136     //NSLog(@"%@", NSStringFromCGRect(self.lblCount.frame));
      137 }
      138 
      139 /*
      140 // Only override drawRect: if you perform custom drawing.
      141 // An empty implementation adversely affects performance during animation.
      142 - (void)drawRect:(CGRect)rect {
      143     // Drawing code
      144 }
      145 */
      146 
      147 @end

       

      posted @ 2015-05-26 09:08  王世楨  閱讀(600)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 高级艳妇交换俱乐部小说| 久99久热免费视频播放| 黑人精品一区二区三区不| 欧洲精品色在线观看| 精品无套挺进少妇内谢| 777米奇影视第四色| 亚洲成av人在线播放无码| 日产国产一区二区不卡| 777米奇色狠狠888俺也去乱 | 国产影片AV级毛片特别刺激| 亚洲成a人片在线观看日本| 免费观看全黄做爰大片| 欧洲美熟女乱av在免费| 超碰人人超碰人人| 久久一级精品久熟女人妻| 国产成人亚洲综合图区 | 日本高清一区免费中文视频| 亚洲成a人片在线观看中| 国产精品 欧美激情 在线播放| 久久一区二区中文字幕| 蜜臀av日韩精品一区二区| 人妻少妇邻居少妇好多水在线| 亚洲精品熟女一区二区| 久久国产乱子精品免费女| 黄色网站免费在线观看| 亚洲欧美中文字幕日韩一区二区| 色综合久久夜色精品国产| 国产精品视频一区二区不卡| 日韩精品国产二区三区| 亚洲国产另类久久久精品网站| 韩国午夜理伦三级| 国产成人亚洲综合| 国产成熟女人性满足视频| 国产情侣激情在线对白| 国产99re热这里只有精品| 亚洲色大成网站WWW永久麻豆| 日韩成人福利视频在线观看| 国语精品国内自产视频| 国产精品不卡一区二区久久| 高清破外女出血AV毛片| 超碰成人人人做人人爽|