首页 > 代码库 > UI基础之UITableView案例QQ好友列表
UI基础之UITableView案例QQ好友列表
一:模型数据
LLFriend
#import <Foundation/Foundation.h>@interface LLFriend : NSObject/** * icon */@property (nonatomic, copy) NSString *icon;/** * intro */@property (nonatomic, copy) NSString *intro;/** * name */@property (nonatomic, copy) NSString *name;/** * vip */@property (nonatomic, assign, getter=isVip) BOOL vip;- (instancetype)initWithDic:(NSDictionary *)dic;+ (instancetype)friendWithDic:(NSDictionary *)dic;@end
#import "LLFriend.h"@implementation LLFriend- (instancetype)initWithDic:(NSDictionary *)dic{ if (self = [super init]) { [self setValuesForKeysWithDictionary:dic]; } return self;}+ (instancetype)friendWithDic:(NSDictionary *)dic{ return [[self alloc] initWithDic:dic];}@end
LLFriendGroup
#import <Foundation/Foundation.h>@interface LLFriendGroup : NSObject/** * friends模型 */@property (nonatomic, strong) NSArray *friends;/** * name */@property (nonatomic, copy) NSString *name;/** * online */@property (nonatomic, assign) int online;/** * 是否合闭 */@property (nonatomic, assign, getter=isOpened) BOOL opened;- (instancetype)initWithDic:(NSDictionary *)dic;+ (instancetype)friendGroupWithDic:(NSDictionary *)dic;+ (NSArray *)friendGroupList;@end
#import "LLFriendGroup.h"#import "LLFriend.h"@implementation LLFriendGroup- (instancetype)initWithDic:(NSDictionary *)dic{ if (self = [super init]) { [self setValuesForKeysWithDictionary:dic]; NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithCapacity:self.friends.count]; for (NSDictionary *dic in self.friends) { LLFriend *friend = [LLFriend friendWithDic:dic]; [tmpArray addObject:friend]; } self.friends = tmpArray; } return self;}+ (instancetype)friendGroupWithDic:(NSDictionary *)dic{ return [[self alloc] initWithDic:dic];}+ (NSArray *)friendGroupList{ NSString *path = [[NSBundle mainBundle] pathForResource:@"friends" ofType:@"plist"]; NSArray *dicArr = [NSArray arrayWithContentsOfFile:path]; NSMutableArray *tmpArr = [[NSMutableArray alloc] initWithCapacity:dicArr.count]; for (NSDictionary *dic in dicArr) { LLFriendGroup *friendGroup = [LLFriendGroup friendGroupWithDic:dic]; [tmpArr addObject:friendGroup]; } return tmpArr;}@end
二:View
LLHeaderView
#import <UIKit/UIKit.h>@class LLFriendGroup;@class LLHeaderView;@protocol LLFriendGroupDelegate <NSObject>@optional- (void)friendGroupDidClickNameView:(LLHeaderView *)friendGroup;@end@interface LLHeaderView : UITableViewHeaderFooterView@property (nonatomic, weak) id<LLFriendGroupDelegate> delegate;@property (nonatomic, strong) LLFriendGroup *group;+ (instancetype)headerViewWith:(UITableView *)tableView;@end
#import "LLHeaderView.h"#import "LLFriendGroup.h"@interface LLHeaderView ()@property (nonatomic, weak) UIButton *nameView;@property (nonatomic, weak) UILabel *onlineView;@end@implementation LLHeaderView+ (instancetype)headerViewWith:(UITableView *)tableView{ static NSString *ID = @"headerView"; LLHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:ID]; if (!headerView) { headerView = [[LLHeaderView alloc] initWithReuseIdentifier:ID]; } return headerView;}- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier{ if (self = [super initWithReuseIdentifier:reuseIdentifier]) { // 按钮 UIButton *nameView = [UIButton buttonWithType:UIButtonTypeCustom]; [self.contentView addSubview:nameView]; self.nameView = nameView; [nameView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; nameView.titleLabel.font = [UIFont systemFontOfSize:16]; [nameView setImage:[UIImage imageNamed:@"buddy_header_arrow"] forState:UIControlStateNormal]; [self.nameView setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg"] forState:UIControlStateNormal]; [self.nameView setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted]; // 设置按钮中内容 nameView.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; nameView.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0); nameView.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0); // 设置按钮图片旋转变形的状态#warning 设置按钮图片旋转变形的状态 nameView.imageView.contentMode = UIViewContentModeCenter; nameView.imageView.clipsToBounds = NO; // 按钮注册事件 [self.nameView addTarget:self action:@selector(clickNameView:) forControlEvents:UIControlEventTouchUpInside]; // label UILabel *onlineView = [[UILabel alloc] init]; [self.contentView addSubview:onlineView]; self.onlineView = onlineView; onlineView.textAlignment = NSTextAlignmentRight; onlineView.font = [UIFont systemFontOfSize:14]; onlineView.textColor = [UIColor grayColor]; } return self;}- (void)clickNameView:(UIButton *)sender{ self.group.opened = !self.group.isOpened; if (self.group.isOpened) { sender.imageView.transform = CGAffineTransformMakeRotation(M_PI_2); } else { sender.imageView.transform = CGAffineTransformMakeRotation(0); } if ([self.delegate respondsToSelector:@selector(friendGroupDidClickNameView:)]) { [self.delegate friendGroupDidClickNameView:self]; }}// 布局子控件- (void)layoutSubviews{#warning 必须调用父类的方法,否则按钮不能点击 [super layoutSubviews]; self.nameView.frame = self.bounds; CGFloat onlineY = 0; CGFloat onlineW = 150; CGFloat onlineH = self.bounds.size.height; CGFloat onlineX = self.bounds.size.width - onlineW - 10; self.onlineView.frame = CGRectMake(onlineX, onlineY, onlineW, onlineH);}- (void)setGroup:(LLFriendGroup *)group{ _group = group; [self.nameView setTitle:group.name forState:UIControlStateNormal]; self.onlineView.text = [NSString stringWithFormat:@"%d/%ld",group.online, group.friends.count]; // set方法中一定要给子控件重新都赋值,否则可能因为cell重用引起的问题 if (self.group.isOpened) { self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2); } else { self.nameView.imageView.transform = CGAffineTransformMakeRotation(0); }}@end
LLFriendCell
#import <UIKit/UIKit.h>@class LLFriend;@interface LLFriendCell : UITableViewCell@property (nonatomic, strong) LLFriend *friendData;+ (instancetype)friendCellWith:(UITableView *)tableView;@end
#import "LLFriendCell.h"#import "LLFriend.h"@implementation LLFriendCell+ (instancetype)friendCellWith:(UITableView *)tableView{ static NSString *ID = @"friendCell"; LLFriendCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if (!cell) { cell = [[LLFriendCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; } return cell;}- (void)setFriendData:(LLFriend *)friendData{ _friendData = friendData; self.imageView.image = [UIImage imageNamed:friendData.icon]; self.textLabel.text = friendData.name; self.detailTextLabel.text = friendData.intro; if (friendData.isVip) { self.textLabel.textColor = [UIColor redColor]; } else { self.textLabel.textColor = [UIColor blackColor]; }}@end
三:
controller
#import "ViewController.h"#import "LLFriend.h"#import "LLFriendGroup.h"#import "LLHeaderView.h"#import "LLFriendCell.h"@interface ViewController ()<LLFriendGroupDelegate>@property (nonatomic, strong) NSArray *friendGroups;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.tableView.sectionHeaderHeight = 44;}#pragma mark - 懒加载数据- (NSArray *)friendGroups{ if (!_friendGroups) { _friendGroups = [LLFriendGroup friendGroupList]; } return _friendGroups;}#pragma mark - 数据源方法- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return self.friendGroups.count;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ LLFriendGroup *group = self.friendGroups[section]; return group.isOpened ? group.friends.count : 0;// return 0;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ LLFriendCell *cell = [LLFriendCell friendCellWith:tableView]; cell.friendData = [self.friendGroups[indexPath.section] friends][indexPath.row]; return cell;}#pragma mark - tableView的代理方法- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ LLHeaderView *headerView = [LLHeaderView headerViewWith:tableView]; headerView.group = self.friendGroups[section]; headerView.delegate = self; return headerView;}#pragma mark - LLFriendGroup代理方法- (void)friendGroupDidClickNameView:(LLHeaderView *)friendGroup{// NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:<#(NSUInteger)#>]// self.tableView reloadSections:<#(NSIndexSet *)#> withRowAnimation:<#(UITableViewRowAnimation)#> [self.tableView reloadData];}- (BOOL)prefersStatusBarHidden{ return YES;}@end
效果:
补充:
背景图片设置 btn setBackgroudImage: state:
2,按钮上默认文字跟图片都是居中对齐的
所以如果想设置其他对齐方式,可以调用按钮的对齐属性
1,contentHorizontalAlignment 水平对齐
2,contentVerticalAlignment 垂直对齐
3,按钮的内边距设置
默认按钮上的文字或图片都是填充整个按钮的宽度跟高度,如果我们想要设置按钮中的内容有跟边框有距离可以设置的属性
1,contentEdgeInsets 按钮上整个内容内边距
2,titleEdgeInsets 文字边距设置
4,按钮上的图片旋转后被拉伸的处理
设置按钮内部的imageView的内容模式为居中,因为默认会填充整个imageView
btn.imageView.contentMode = UIViewContentModeCenter
btn.imageView.clipsToBounds = NO; 默认为yes表示超出的部分减掉
5:
- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
NSLog(@"%f", self.frame.size.height); // height为0;
}
init方法中,self对象和它父类的frame初始化过程中都为0;
所以没法确定子类的frame,在layoutSubview方法中父类的frame已经确定了
UI基础之UITableView案例QQ好友列表