iOS開發UI篇—使用UItableview完成一個簡單的QQ好友列表(二)

1、實現效果數組

           

2、實現代碼緩存

1.數據模型部分app

 YYQQGroupModel.h文件ide

 1 //
 2 //  YYQQGroupModel.h
 3 //  02-QQ好友列表(基本數據的加載)
 4 //
 5 //  Created by apple on 14-5-31.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 
11 @interface YYQQGroupModel : NSObject
12 /**
13  *  名稱屬性
14  */
15 @property(nonatomic,copy)NSString *name;
16 /**
17  *  是否在線
18  */
19 @property(nonatomic,copy)NSString *online;
20 /**
21  *  好友列表
22  */
23 @property(nonatomic,strong)NSArray *friends;
24 
25 //記錄當前組是否要打開
26 @property(nonatomic,assign,getter = isOpen)BOOL open;
27 
28 -(instancetype)initWithDict:(NSDictionary *)dict;
29 +(instancetype) qqGroupModelWithDict:(NSDictionary *)dict;
30 @end

 YYQQGroupModel.m文件字體

 1 //
 2 //  YYQQGroupModel.m
 3 //  02-QQ好友列表(基本數據的加載)
 4 //
 5 //  Created by apple on 14-5-31.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import "YYQQGroupModel.h"
10 #import "YYFriendsModel.h"
11 
12 @implementation YYQQGroupModel
13 -(instancetype)initWithDict:(NSDictionary *)dict
14 {
15     if (self=[super init]) {
16         //將字典轉換爲模型
17         [self setValuesForKeysWithDictionary:dict];
18         
19         //定義一個數組來保存轉換後的模型
20         NSMutableArray *models=[NSMutableArray arrayWithCapacity:self.friends.count];
21         for (NSDictionary *dict in self.friends) {
22             YYFriendsModel *friends=[YYFriendsModel friendsWithDict:dict];
23             [models addObject:friends];
24         }
25         _friends=[models copy];
26     }
27     return self;
28 }
29 
30 +(instancetype)qqGroupModelWithDict:(NSDictionary *)dict
31 {
32     return  [[self alloc]initWithDict:dict];
33 }
34 @end

YYFriendsModel.h文件atom

 1 //
 2 //  YYFriendsModel.h
 3 //  02-QQ好友列表(基本數據的加載)
 4 //
 5 //  Created by apple on 14-5-31.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 
11 @interface YYFriendsModel : NSObject
12 /**
13  *  每一個好友的名稱
14  */
15 @property(nonatomic,copy)NSString *name;
16 /**
17  *每一個好友的頭像
18  */
19 @property(nonatomic,copy)NSString *icon;
20 /**
21  *  每一個好友的個性簽名
22  */
23 @property(nonatomic,copy)NSString *intro;
24 /**
25  *  該好友是不是vip
26  */
27 @property(nonatomic,assign,getter = isVip)BOOL vip;
28 
29 -(instancetype)initWithDict:(NSDictionary *)dict;
30 +(instancetype)friendsWithDict:(NSDictionary *)dict;
31 @end

YYFriendsModel.m文件spa

 1 //
 2 //  YYFriendsModel.m
 3 //  02-QQ好友列表(基本數據的加載)
 4 //
 5 //  Created by apple on 14-5-31.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import "YYFriendsModel.h"
10 
11 @implementation YYFriendsModel
12 -(instancetype)initWithDict:(NSDictionary *)dict
13 {
14     if (self=[super init]) {
15         [self setValuesForKeysWithDictionary:dict];
16     }
17     return self;
18 }
19 
20 +(instancetype)friendsWithDict:(NSDictionary *)dict
21 {
22     return [[self alloc]initWithDict:dict];
23 }
24 @end

2.視圖部分代理

YYfriendCell.h文件code

 1 //
 2 //  YYfriendCell.h
 3 //  02-QQ好友列表(基本數據的加載)
 4 //
 5 //  Created by apple on 14-5-31.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 @class YYFriendsModel;
11 @interface YYfriendCell : UITableViewCell
12 
13 @property(nonatomic,strong)YYFriendsModel *friends;
14 
15 +(instancetype)cellWithTableview:(UITableView *)tableView;
16 @end

YYfriendCell.m文件orm

 1 //
 2 //  YYfriendCell.m
 3 //  02-QQ好友列表(基本數據的加載)
 4 //
 5 //  Created by apple on 14-5-31.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import "YYfriendCell.h"
10 #import "YYFriendsModel.h"
11 //私有擴展
12 @interface YYfriendCell()
13 
14 
15 @end
16 @implementation YYfriendCell
17 
18 +(YYfriendCell *)cellWithTableview:(UITableView *)tableView
19 {
20     static NSString *identifier=@"qq";
21     YYfriendCell *cell=[tableView dequeueReusableCellWithIdentifier:identifier];
22     if (cell==nil) {
23         //這裏使用系統自帶的樣式
24         cell=[[YYfriendCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
25         NSLog(@"建立一個cell");
26     }
27     return cell;
28 }
29 
30 -(void)setFriends:(YYFriendsModel *)friends
31 {
32     _friends=friends;
33     //1.設置頭像
34     self.imageView.image=[UIImage imageNamed:_friends.icon];
35        //2.設置暱稱
36     self.textLabel.text=_friends.name;
37     
38      //3.設置簡介
39     self.detailTextLabel.text=_friends.intro;
40  //判斷是不是會員
41     
42     /**
43      *  這裏有個注意點,若是不寫else設置爲黑色,會怎麼樣?
44      */
45     if (_friends.isVip) {
46         [self.textLabel setTextColor:[UIColor redColor]];
47     }else
48     {
49     [self.textLabel setTextColor:[UIColor blackColor]];
50     }
51      //調整字體的大小
52     self.textLabel.font=[UIFont systemFontOfSize:15.f];
53     self.detailTextLabel.font=[UIFont systemFontOfSize:10.f];
54 }
55 @end

YYHeaderView.h文件

 1 //
 2 //  YYHeaderView.h
 3 //  02-QQ好友列表(基本數據的加載)
 4 //
 5 //  Created by apple on 14-6-1.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @class YYQQGroupModel,YYHeaderView;
12 
13 //商量一個協議
14 @protocol YYHeaderViewDelegate <NSObject>
15 -(void)headerViewDidClickHeaderView:(YYHeaderView *)headerView;
16 @end
17 
18 @interface YYHeaderView : UITableViewHeaderFooterView
19 
20 @property(nonatomic,strong)YYQQGroupModel *group;
21 //提供一個類方法,建立一個頭部視圖
22 +(instancetype)headerWithTableView:(UITableView *)tableView;
23 
24 
25 //delegate遵照YYHeaderViewDelegate這個協議,可使用協議中的方法
26 @property(nonatomic,weak)id<YYHeaderViewDelegate> delegate;
27 @end

YYHeaderView.m文件

  1 //
  2 //  YYHeaderView.m
  3 //  02-QQ好友列表(基本數據的加載)
  4 //
  5 //  Created by apple on 14-6-1.
  6 //  Copyright (c) 2014年 itcase. All rights reserved.
  7 //
  8 
  9 #import "YYHeaderView.h"
 10 #import "YYQQGroupModel.h"
 11 
 12 @interface YYHeaderView()
 13 @property(nonatomic,strong)UIButton *btn;
 14 @property(nonatomic,strong)UILabel *lab;
 15 @end
 16 @implementation YYHeaderView
 17 
 18 
 19 //建立一個自定義的頭部分組視圖
 20 +(instancetype)headerWithTableView:(UITableView *)tableView
 21 {
 22     static NSString *indentifier=@"header";
 23     //先到緩存池中去取數據
 24     YYHeaderView *headerview=[tableView dequeueReusableCellWithIdentifier:indentifier];
 25     //若是沒有,則本身建立
 26     if (headerview==nil) {
 27         headerview=[[YYHeaderView alloc]initWithReuseIdentifier:indentifier];
 28     }
 29     //返回一個頭部視圖
 30     return headerview;
 31 }
 32 
 33 #warning 注意在構造方法中爲控件設置的frame是無效的
 34 -(id)initWithReuseIdentifier:(NSString *)reuseIdentifier
 35 {
 36     //初始化父類中的構造方法
 37     if (self=[super initWithReuseIdentifier:reuseIdentifier]) {
 38         //建立一個按鈕
 39         UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
 40         //設置按鈕的屬性
 41         //設置普通狀態下按鈕的背景圖片
 42         [btn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg"] forState:UIControlStateNormal];
 43         //設置高亮狀態下按鈕的背景圖片
 44         [btn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted];
 45         
 46         //設置按鈕上的小三角圖片
 47         [btn setImage:[UIImage imageNamed:@"buddy_header_arrow"] forState:UIControlStateNormal];
 48         //設置按鈕上信息的對其方式爲左對齊
 49         btn.contentHorizontalAlignment=UIControlContentHorizontalAlignmentLeft;
 50         //設置小三角圖片的內邊距
 51         btn.contentEdgeInsets=UIEdgeInsetsMake(0, 20, 0, 0);
 52         //設置按鈕上文字距離小三角圖片的距離
 53         btn.titleEdgeInsets=UIEdgeInsetsMake(0, 20, 0, 0);
 54         //設置按鈕上分組標題的文本顏色(默認是白色)
 55         //[btn setTintColor:[UIColor blackColor]];
 56         [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
 57         //添加按鈕的點擊事件
 58         [btn addTarget:self action:@selector(btnOnclick:) forControlEvents:UIControlEventTouchUpInside];
 59         
 60         // 設置btn中的圖片不填充整個imageview
 61         btn.imageView.contentMode = UIViewContentModeCenter;
 62         // 超出範圍的圖片不要剪切
 63                // btn.imageView.clipsToBounds = NO;
 64         btn.imageView.layer.masksToBounds = NO;
 65         
 66         //把按鈕添加到視圖
 67         [self addSubview:btn];
 68         self.btn=btn;
 69         
 70         //建立一個lab
 71         UILabel *lab=[[UILabel alloc]init];
 72         //設置在線人數的對齊方式爲右對齊
 73         lab.textAlignment=NSTextAlignmentRight;
 74         //設置在線人數的文本顏色爲灰色
 75         lab.textColor=[UIColor grayColor];
 76         [self addSubview:lab];
 77         self.lab=lab;
 78     }
 79     return self;
 80 }
 81 
 82 
 83 -(void)btnOnclick:(UIButton *)btn
 84 {
 85     NSLog(@"按鈕被點擊了");
 86     //修改模型的isopen屬性
 87     //1.修改模型數據
 88     self.group.open=!self.group.isOpen;
 89     //2.刷新表格
 90     //(刷新表格的功能由控制器完成,在這裏能夠設置一個代理),當按鈕被點擊的時候,就通知代理對錶格進行刷新
 91     //通知代理
 92     if ([self.delegate respondsToSelector:@selector(headerViewDidClickHeaderView:)]) {
 93         [self.delegate headerViewDidClickHeaderView:self];
 94     }
 95 }
 96 
 97 //當控件的frame值改變時,會自動調用該方法,故能夠在該方法中設置控件的frame;
 98 -(void)layoutSubviews
 99 {
100 #warning 必定不要忘記調用父類的方法
101     [super layoutSubviews];
102     //設置按鈕的frame和頭部視圖同樣大小
103     self.btn.frame=self.bounds;
104     
105     //設置lab的frame
106     CGFloat padding=20;
107     CGFloat labW=50;
108     CGFloat labH=self.frame.size.height;
109     CGFloat labY=0;
110     CGFloat labX=self.frame.size.width-padding-labW;
111     self.lab.frame=CGRectMake(labX, labY, labW, labH);
112 }
113 
114 #pragma mark - 當一個控件被添加到其它視圖上的時候會調用如下方法
115 // 已經被添加到父視圖上的時候會調用
116 - (void)didMoveToSuperview
117 {
118     NSLog(@"已經添加到視圖了");
119     // 在這個方法中就快要拿到最新的被添加到tableview上的頭部視圖修改它的圖片
120     if (self.group.isOpen) {
121         //讓小三角圖片向下旋轉
122         self.btn.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
123     }
124 }
125 
126 // 即將被添加到父視圖上的時候會調用
127 - (void)willMoveToSuperview:(UIView *)newSuperview
128 {
129      NSLog(@"將要添加到視圖了");
130 }
131 
132 
133 //重寫get方法,設置數據
134 -(void)setGroup:(YYQQGroupModel *)group
135 {
136     _group=group;
137     //設置分組標題
138 
139     //self.btn.titleLabel.text=_group.name;
140     #warning 請注意在設置按鈕的文本時,必定要設置按鈕的狀態,像上面這樣設置不會顯示
141     [self.btn setTitle:_group.name forState:UIControlStateNormal];
142     NSLog(@"%@",self.btn.titleLabel.text);
143     //設置在線人數
144     self.lab.text=[NSString stringWithFormat:@"%@/%d",_group.online,_group.friends.count];
145 }
146 
147 @end

3.控制器部分

YYViewController.h文件

 1 //
 2 //  YYViewController.h
 3 //  02-QQ好友列表(基本數據的加載)
 4 //
 5 //  Created by apple on 14-5-31.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @interface YYViewController : UITableViewController
12 
13 @end

YYViewController.m文件

  1 //
  2 //  YYViewController.m
  3 //  02-QQ好友列表(基本數據的加載)
  4 //
  5 //  Created by apple on 14-5-31.
  6 //  Copyright (c) 2014年 itcase. All rights reserved.
  7 //
  8 
  9 #import "YYViewController.h"
 10 #import "YYQQGroupModel.h"
 11 #import "YYfriendCell.h"
 12 #import "YYFriendsModel.h"
 13 #import "YYHeaderView.h"
 14 
 15 @interface YYViewController ()<YYHeaderViewDelegate>
 16 /**
 17  *  用來保存全部的分組數據
 18  */
 19 @property(nonatomic,strong)NSArray *groupFriends;
 20 @end
 21 
 22 @implementation YYViewController
 23 #pragma mark-懶加載
 24 //1.先拿到數據,實現懶加載
 25 -(NSArray *)groupFriends
 26 {
 27     if (_groupFriends==nil) {
 28         NSString *fullpath=[[NSBundle mainBundle]pathForResource:@"friends.plist" ofType:nil];
 29         NSArray *arrayM=[NSArray arrayWithContentsOfFile:fullpath];
 30         
 31         NSMutableArray *models=[NSMutableArray arrayWithCapacity:arrayM.count];
 32         for (NSDictionary *dict in arrayM) {
 33             YYQQGroupModel *group=[YYQQGroupModel qqGroupModelWithDict:dict];
 34             [models addObject:group];
 35         }
 36         _groupFriends=[models copy];
 37     }
 38     return _groupFriends;
 39 }
 40 
 41 - (void)viewDidLoad
 42 {
 43     [super viewDidLoad];
 44      self.tableView.sectionHeaderHeight = 100;
 45         
 46 }
 47 
 48 #pragma mark-  設置數據源
 49 //返回多少組
 50 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
 51 {
 52     return self.groupFriends.count;
 53 }
 54 //每組返回多少行
 55 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 56 {
 57 //    //取出對應的組模型
 58         YYQQGroupModel *group=self.groupFriends[section];
 59 //    //返回對應組中的好友數
 60 //    return group.friends.count;
 61     
 62     //在這裏進行判斷,若是該組收攏,那就返回0行,若是該組打開,就返回實際的行數
 63 //    if (group.isOpen) {
 64 //        return group.friends.count;
 65 //    }else
 66 //    {
 67 //        return 0;
 68 //    }
 69     
 70     if (group.isOpen) {
 71         // 表明要展開
 72         return group.friends.count;
 73     }else
 74     {
 75         // 表明要合攏
 76         return 0;
 77     }
 78 }
 79 //每組每行的內容
 80 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 81 {
 82     //1.建立cell
 83     YYfriendCell *cell=[YYfriendCell cellWithTableview:tableView];
 84 
 85     //2.設置cell
 86     YYQQGroupModel *group=self.groupFriends[indexPath.section];
 87     YYFriendsModel *friends=group.friends[indexPath.row];
 88     cell.friends=friends;
 89     //3.返回一個cell
 90     return cell;
 91 }
 92 
 93 
 94 #pragma mark - 代理方法
 95 // 當一個分組標題進入視野的時候就會調用該方法
 96 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
 97 {
 98 //    //    1.建立頭部視圖
 99 //    UIView *view = [[UIView alloc] init];
100 //    view.backgroundColor = [UIColor grayColor];
101 //    //    2.返回頭部視圖
102 //    return view;
103     
104     //建立自定義的頭部視圖
105     YYHeaderView *headerview=[YYHeaderView headerWithTableView:tableView];
106     
107     //設置當前控制器爲代理
108     headerview.delegate=self;
109     //設置頭部視圖的數據
110     YYQQGroupModel *groupmodel=self.groupFriends[section];
111     headerview.group=groupmodel;
112     //返回頭部視圖
113     return headerview;
114 }
115 
116 
117 #pragma mark - YYHeaderViewDelegate
118 -(void)headerViewDidClickHeaderView:(YYHeaderView *)headerView
119 {
120     //從新調用數據源的方法刷新數據
121     [self.tableView reloadData];
122 }
123 //設置分組頭部標題的高度
124 -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
125 {
126     return 30;
127 }
128 
129 #pragma mark  隱藏狀態欄
130 -(BOOL)prefersStatusBarHidden
131 {
132     return YES;
133 }
134 @end

3、代碼說明

1.項目文件結構

2.注意點

(1)調整字體的大小:    self.textLabel.font=[UIFont systemFontOfSize:15.f];

(2)-(void)layoutSubviews方法。該方法在控件的frame被改變的時候就會調用,這個方法通常用於調整子控件的位置,注意必定要調用[super layoutSubviews];

(3)但凡在init方法中獲取到的frame都是0;

(4)若是控件不顯示,有如下一些排錯方法

a.frame爲空(沒有設置frame)
b.hidden是否爲YES
c.alpha<=0.1(透明度)
d.沒有添加到父控件中
e.查看父控件以上幾點

(5)請注意在設置按鈕的文本時,必定要設置按鈕的狀態

正確:[self.btn setTitle:_group.name forState:UIControlStateNormal];
錯誤: self.btn.titleLabel.text=_group.name;

(6)調用構造方法時,必定要先初始化父類的方法,先判斷,再進行本身屬性的初始化

self=[super initWithReuseIdentifier:reuseIdentifier]
if(self)
{
……
}
(7)當一個控件被添加到其它視圖上的時候會調用如下方法

1) 已經被添加到父視圖上的時候會調用- (void)didMoveToSuperview

2) 即將被添加到父視圖上的時候會調用- (void)willMoveToSuperview:(UIView *)newSuperview

(8)圖片填充知識

   1)設置btn中的圖片不填充整個imageview btn.imageView.contentMode = UIViewContentModeCenter;

   2)超出範圍的圖片不要剪切

  //btn.imageView.clipsToBounds = NO;

  btn.imageView.layer.masksToBounds = NO;

4、補充(代理)

設置代理的幾個步驟
(1)若是一個視圖中的某個按鈕被點擊了,這個時候須要去主控制器中刷新數據。有一種作法是,讓這個視圖擁有控制器這個屬性,而後當按鈕被點擊的時候去利用該屬性去作刷新數據的操做。另外一種作法是把控制器設置爲這個視圖的代理,當視圖中的某個按鈕被點擊的時候,通知它的代理(主控制器)去幹刷新數據這件事。
(2)要成爲代理是由條件的,有如下幾個步驟
1).雙方約定一個協議(代理協議,注意命名規範),在視圖中自定義一個協議,協議中提供一個方法。

@protocol YYHeaderViewDelegate <NSObject>

-(void)headerViewDidClickHeaderView:(YYHeaderView *)headerView;

@end

2).在視圖中添加一個id類型的屬性變量,任何人只要遵照了約定協議的均可以成爲它的代理。

//delegate遵照YYHeaderViewDelegate這個協議,可使用協議中的方法

@property(nonatomic,weak)id<YYHeaderViewDelegate> delegate;

3).在控制器中,遵照自定義的代理協議,就可使用代理提供的方法,在這個方法中對數據進行刷新。

@interface YYViewController ()<YYHeaderViewDelegate>

-(void)headerViewDidClickHeaderView:(YYHeaderView *)headerView

{

    [self.tableView reloadData];

}

4).把控制器設置做爲按鈕點擊事件的代理。

headerview.delegate=self;

相關文章
相關標籤/搜索