iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(一)
一、项目结构和plist文件
二、实现代码
1.说明:
主控制器直接继承UITableViewController
1 // Created by 鑫 on 14-10-13. 2 // Copyright (c) 2014年 梁镋鑫. All rights reserved. 3 // 4 5 #import <UIKit/UIKit.h> 6 7 @interface TXViewController : UITableViewController 8 9 @end
在storyboard中进行了关联
2.代码
数据模型部分:
TXFriendGroup.h文件
1 // Created by 鑫 on 14-10-13. 2 // Copyright (c) 2014年 梁镋鑫. All rights reserved. 3 // 4 5 #import <Foundation/Foundation.h> 6 7 @interface TXFriendGroup : NSObject 8 @property (nonatomic, copy) NSString *name; 9 /** 10 * 数组中装的都是TXFriend模型 11 */ 12 @property (nonatomic, strong) NSArray *friends; 13 @property (nonatomic, assign) int online; 14 15 + (instancetype)groupWithDict:(NSDictionary *)dict; 16 - (instancetype)initWithDict:(NSDictionary *)dict; 17 18 19 @end
TXFriendGroup.m文件
1 #import "TXFriendGroup.h" 2 #import "TXFriend.h" 3 @implementation TXFriendGroup 4 + (instancetype)groupWithDict:(NSDictionary *)dict 5 { 6 return [[self alloc] initWithDict:dict]; 7 } 8 9 - (instancetype)initWithDict:(NSDictionary *)dict 10 { 11 if (self = [super init]) { 12 // 1.注入所有属性将字典转换为模型 13 [self setValuesForKeysWithDictionary:dict]; 14 15 // 2.特殊处理friends属性定义一个数组来保存转换后的模型 16 NSMutableArray *friendArray = [NSMutableArray array]; 17 for (NSDictionary *dict in self.friends) { 18 TXFriend *friend = [TXFriend friendWithDict:dict]; 19 [friendArray addObject:friend]; 20 } 21 self.friends = friendArray; 22 } 23 return self; 24 } 25 26 @end
TXFriend.h文件
1 #import <Foundation/Foundation.h> 2 3 @interface TXFriend : NSObject 4 @property (nonatomic, copy) NSString *name; 5 @property (nonatomic, copy) NSString *icon; 6 @property (nonatomic, copy) NSString *intro; 7 @property (nonatomic, assign, getter = isVip) BOOL vip; 8 9 + (instancetype)friendWithDict:(NSDictionary *)dict; 10 - (instancetype)initWithDict:(NSDictionary *)dict; 11 12 @end
TXFriend.m文件
1 #import "TXFriend.h" 2 3 @implementation TXFriend 4 + (instancetype)friendWithDict:(NSDictionary *)dict 5 { 6 return [[self alloc] initWithDict:dict]; 7 } 8 9 - (instancetype)initWithDict:(NSDictionary *)dict 10 { 11 if (self = [super init]) { 12 [self setValuesForKeysWithDictionary:dict]; 13 } 14 return self; 15 } 16 17 @end
视图部分
TXFriendCell.h文件
1 / 2 // TXFriendCell.h 3 // 04-QQ好友列表 4 // 5 // Created by 鑫 on 14-10-14. 6 // Copyright (c) 2014年 梁镋鑫. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 @class TXFriend; 11 @interface TXFriendCell : UITableViewCell 12 + (instancetype)cellWithTableView:(UITableView *)tableView; 13 // friend是C++的关键字,不能用friend作为属性名 14 @property (nonatomic, strong) TXFriend *friendData; 15 @end
TXFriendCell.m文件
1 #import "TXFriendCell.h" 2 #import "TXFriend.h" 3 @implementation TXFriendCell 4 5 + (instancetype)cellWithTableView:(UITableView *)tableView 6 { 7 static NSString *ID = @"friend"; 8 TXFriendCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 9 if (cell == nil) { 10 //这里使用系统自带的样式 11 cell = [[TXFriendCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; 12 } 13 return cell; 14 } 15 16 - (void)setFriendData:(TXFriend *)friendData 17 { 18 _friendData = friendData; 19 20 self.imageView.image = [UIImage imageNamed:friendData.icon]; 21 self.textLabel.text = friendData.name; 22 self.detailTextLabel.text = friendData.intro; 23 } 24 25 @end
TXHeaderView.h文件
1 // 2 // Created by 鑫 on 14-10-14. 3 // Copyright (c) 2014年 梁镋鑫. All rights reserved. 4 // 5 6 #import <UIKit/UIKit.h> 7 @class TXFriendGroup; 8 @interface TXHeaderView : UITableViewHeaderFooterView 9 + (instancetype)headerViewWithTableView:(UITableView *)tableView; 10 11 @property (nonatomic, strong) TXFriendGroup *group; 12 13 14 @end
TXHeaderView.m文件
1 #import "TXFriendGroup.h" 2 3 #import "TXHeaderView.h" 4 /** 5 某个控件出不来: 6 1.frame的尺寸和位置对不对 7 8 2.hidden是否为YES 9 10 3.有没有添加到父控件中 11 12 4.alpha 是否 < 0.01 13 14 5.被其他控件挡住了 15 16 6.父控件的前面5个情况 17 */ 18 19 @interface TXHeaderView() 20 @property (nonatomic, weak) UILabel *countView; 21 @property (nonatomic, weak) UIButton *nameView; 22 @end 23 24 @implementation TXHeaderView 25 26 + (instancetype)headerViewWithTableView:(UITableView *)tableView 27 { 28 static NSString *ID = @"header"; 29 TXHeaderView *header = [tableView dequeueReusableHeaderFooterViewWithIdentifier:ID]; 30 if (header == nil) { 31 header = [[TXHeaderView alloc] initWithReuseIdentifier:ID]; 32 } 33 return header; 34 } 35 36 /** 37 * 在这个初始化方法中,TXHeaderView的frame\bounds没有值 38 */ 39 - (id)initWithReuseIdentifier:(NSString *)reuseIdentifier 40 { 41 if (self = [super initWithReuseIdentifier:reuseIdentifier]) { 42 // 添加子控件 43 // 1.添加按钮 44 UIButton *nameView = [UIButton buttonWithType:UIButtonTypeCustom]; 45 // 背景图片 46 [nameView setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg"] forState:UIControlStateNormal]; 47 [nameView setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted]; 48 // 设置按钮内部的左边箭头图片 49 [nameView setImage:[UIImage imageNamed:@"buddy_header_arrow"] forState:UIControlStateNormal]; 50 [nameView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 51 // 设置按钮的内容左对齐 52 nameView.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; 53 // 设置按钮的内边距 54 // nameView.imageEdgeInsets 55 nameView.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0); 56 nameView.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0); 57 [self.contentView addSubview:nameView]; 58 self.nameView = nameView; 59 60 // 2.添加好友数 61 UILabel *countView = [[UILabel alloc] init]; 62 countView.textAlignment = NSTextAlignmentRight; 63 countView.textColor = [UIColor grayColor]; 64 [self.contentView addSubview:countView]; 65 self.countView = countView; 66 } 67 return self; 68 } 69 70 /** 71 * 当一个控件的frame发生改变的时候就会调用 72 * 73 * 一般在这里布局内部的子控件(设置子控件的frame) 74 */ 75 - (void)layoutSubviews 76 { 77 #warning 一定要调用super的方法 78 [super layoutSubviews]; 79 80 // 1.设置按钮的frame 81 self.nameView.frame = self.bounds; 82 83 // 2.设置好友数的frame 84 CGFloat countY = 0; 85 CGFloat countH = self.frame.size.height; 86 CGFloat countW = 150; 87 CGFloat countX = self.frame.size.width - 10 - countW; 88 self.countView.frame = CGRectMake(countX, countY, countW, countH); 89 } 90 91 - (void)setGroup:(TXFriendGroup *)group 92 { 93 _group = group; 94 95 // 1.设置按钮文字(组名) 96 [self.nameView setTitle:group.name forState:UIControlStateNormal]; 97 98 // 2.设置好友数(在线数/总数) 99 self.countView.text = [NSString stringWithFormat:@"%d/%d", group.online, group.friends.count]; 100 } 101 102 @end
主控制器部分
YYViewController.m文件
1 #import "TXViewController.h" 2 #import "TXFriendGroup.h" 3 #import "TXFriend.h" 4 #import "TXHeaderView.h" 5 #import "TXFriendCell.h" 6 7 @interface TXViewController () 8 @property (nonatomic, strong) NSArray *groups; 9 @end 10 11 @implementation TXViewController 12 13 - (void)viewDidLoad 14 { 15 [super viewDidLoad]; 16 17 // 每一行cell的高度 18 self.tableView.rowHeight = 50; 19 // 每一组头部控件的高度 20 self.tableView.sectionHeaderHeight = 44; 21 } 22 //1.先拿到数据,实现懒加载 23 - (NSArray *)groups 24 { 25 if (_groups == nil) { 26 NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"friends.plist" ofType:nil]]; 27 28 NSMutableArray *groupArray = [NSMutableArray array]; 29 for (NSDictionary *dict in dictArray) { 30 TXFriendGroup *group = [TXFriendGroup groupWithDict:dict]; 31 [groupArray addObject:group]; 32 } 33 34 _groups = groupArray; 35 } 36 return _groups; 37 } 38 39 - (BOOL)prefersStatusBarHidden 40 { 41 return YES; 42 } 43 44 #pragma mark - 数据源方法 45 //返回多少组 46 //为什么这里不会智能提示?因为这些方法是uitableview协议里的,默认并没有遵守协议,让主控制器类继承uitableviewcontroller后,就已经遵守了 47 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 48 { 49 return self.groups.count; 50 } 51 //每组每行的内容 52 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 53 { 54 TXFriendGroup *group = self.groups[section]; 55 return group.friends.count; 56 } 57 58 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 59 { 60 // 1.创建cell 61 TXFriendCell *cell = [TXFriendCell cellWithTableView:tableView]; 62 63 // 2.设置cell的数据 64 TXFriendGroup *group = self.groups[indexPath.section]; 65 cell.friendData = group.friends[indexPath.row]; 66 67 return cell; 68 } 69 70 /** 71 * 返回每一组需要显示的头部标题(字符出纳)// 当一个分组标题进入视野的时候就会调用该方法 72 */ 73 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 74 { 75 // 1.创建头部控件 76 TXHeaderView *header = [TXHeaderView headerViewWithTableView:tableView]; 77 78 // 2.给header设置数据(给header传递模型) 79 header.group = self.groups[section]; 80 81 return header; 82 } 83 //设置分组头部标题的高度 84 -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 85 { 86 return 44; 87 } 88 @end
实现的简陋效果:
三、注意点
(1)设置头部视图的方法
(2)在重写set方法时,应该考虑到回滚。