iOS QQ列表效果实现

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

效果如下:

实现效果主要分为两个部分:

  1. 数据模型

  2. tableview

要实现tableview需要实现DataSource和delegate

datasource主要作用在于显示什么数据

delegate主要作用是事件响应即处理

代码如下:.h

// controller
@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, retain) NSMutableArray *dataList;   // 数据
@property (nonatomic, retain) UITableView *tableView;

@end

.m 文件

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self initDataList];   // 初始化数据
    
    // 向下移20
    CGRect frame = self.view.frame;
    frame.origin.y = 20;
    frame.size.height = frame.size.height - 20;
    self.tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain];
    
    // 设置委托
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    [self.view addSubview:self.tableView];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - DataSource实现
// 一共几个section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [self.dataList count];
}

// 每个section下有多少个组
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    List *list = [self.dataList objectAtIndex:section];
    NSMutableArray *array = list.groups;
    NSInteger all = [array count];
    for (Group *group in array) {
        if (group.isDelop) {
            all = all + [group.friends count];
        }
    }
    return all;
}

// 显示每个cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([self isGroup:indexPath]) {
        return [self getGroupCell:tableView and:indexPath];   // 分组的cell
    }
    return [self getFriendCell:tableView and:indexPath];      // 好友cell
}

/*
 * 获得section标题
 **/
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    List *list = [self.dataList objectAtIndex:section];
    return list.title;
}

#pragma mark - 点击事件
// 单击的处理,若是分组 则展开,否则不处理
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    Group *group = [self isGroup:indexPath];
    // 如果点击的是分组,则取当前状态的反并更新数据
    if (group) {
        group.isDelop = !group.isDelop;
        [self.tableView reloadData];
    }
}

#pragma mark - 获取点击位置的数据
/*
 * 所点位置是否是分组,返回所点分组数据
 **/
- (Group *)isGroup:(NSIndexPath *)indexPath {
    int num = -1;
    NSUInteger index = indexPath.row;
    
    List *list = [_dataList objectAtIndex:indexPath.section];
    NSMutableArray *groups = list.groups;
    for (Group *group in groups) {
        num++;
        if (index == num) {
            return group;
        }
        if (group.isDelop) {
            num += [group.friends count];
            if (index <= num) {
                return nil;
            }
        }
    }
    return nil;
}

/*
 * 所点位置是否是好友,并返回所点好友数据
 **/
- (Friend *)isFriend:(NSIndexPath *)indexPath {
    int num = -1;
    NSUInteger index = indexPath.row;
    
    List *list = [_dataList objectAtIndex:indexPath.section];  // 获取点的section
    NSMutableArray *groups = list.groups;                      // 获取section下的所有分组
    for (Group *group in groups) {
        num++;
        if (group.isDelop) {
            int temp = num;
            num += [group.friends count];
            if (index <= num) {
                int k = index - temp - 1;
                return [group.friends objectAtIndex:k];
            }
        }
    }
    return nil;
}

#pragma mark - 初始化cell
/*
 * 设置分组的cell
 **/
- (UITableViewCell *)getGroupCell:(UITableView *)tableView and:(NSIndexPath *)indexPath {
    Group *nowGroup = [self isGroup:indexPath];
    static NSString *CellWithIdentifier = @"GroupCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellWithIdentifier];
        cell.backgroundColor = [UIColor colorWithRed:227/250.0 green:168/250.0 blue:105/250.0 alpha:1];
    }
    
    cell.textLabel.text = nowGroup.title;
    cell.detailTextLabel.text = nowGroup.detail;
    if (nowGroup.isDelop) {
        cell.imageView.image = [UIImage imageNamed:@"collect.png"];
    }
    else {
        cell.imageView.image = [UIImage imageNamed:@"tomore.png"];
    }
    return cell;
}

/*
 * 设置好友cell
 **/
- (UITableViewCell *)getFriendCell:(UITableView *)tableView and:(NSIndexPath *)indexPath {
    Friend *nowFriend = [self isFriend:indexPath];
    static NSString *CellWithIdentifier = @"FriendCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellWithIdentifier];
    }
    // 设置cell数据
    cell.textLabel.text = nowFriend.name;
    cell.detailTextLabel.text = nowFriend.state;
    cell.imageView.image = [UIImage imageNamed:nowFriend.image];
    return cell;
}

#pragma mark - 大小样式设置
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([self isGroup:indexPath]) {
        return 30;   // 分组高
    }
    return 40;       // 好友的行高
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 20;
}

#pragma mark - 所显示的数据
/*
 * 数据初始化构造
 **/
- (void)initDataList {
    Friend *friend1 = [[Friend alloc] initWithImage:@"back1.jpg" name:@"苦海无涯" states:@"[在线] 哎 心疼!!"];
    Friend *friend2 = [[Friend alloc] initWithImage:@"back2.jpg" name:@"段天涯" states:@"[在线] 心疼!!"];
    Friend *friend3 = [[Friend alloc] initWithImage:@"back3.jpg" name:@"小妹妹" states:@"[在线] 疼!!"];
    Friend *friend4 = [[Friend alloc] initWithImage:@"back4.jpg" name:@"呼哈" states:@"[在线]心疼!!"];
    
    NSMutableArray *array1 = [NSMutableArray arrayWithObjects:friend1, friend2, friend3, friend4, nil];
    Group *group1 = [[Group alloc] initWithTitle:@"家人" delop:NO friends:array1];
    group1.detail = @"4/4";
    
    Friend *friend5 = [[Friend alloc] initWithImage:@"back5.jpg" name:@"段" states:@"[在线] 心疼!!"];
    Friend *friend6 = [[Friend alloc] initWithImage:@"back6.jpg" name:@"小商人" states:@"[在线] 疼!!"];
    Friend *friend7 = [[Friend alloc] initWithImage:@"back7.jpg" name:@"大哥" states:@"[离线] 心疼!!"];
    
    NSMutableArray *array2 = [NSMutableArray arrayWithObjects:friend5, friend6, friend7, nil];
    Group *group2 = [[Group alloc] initWithTitle:@"朋友" delop:NO friends:array2];
    group2.detail = @"2/3";
    
    NSMutableArray *l1 = [NSMutableArray arrayWithObjects:group1, group2, nil];
    List *list1 = [[List alloc] initWithTitle:@"我的好友" groups:l1];
    
    Friend *mobile = [[Friend alloc] initWithImage:@"back1.jpg" name:@"我的手机" states:@"[离线]手机未上线"];
    NSMutableArray *array = [NSMutableArray arrayWithObjects:mobile, nil];
    Group *group = [[Group alloc] initWithTitle:@"我的设备" delop:NO friends:array];
    group.detail = @"0/1";
    
    NSMutableArray *l2 = [NSMutableArray arrayWithObjects:group, nil];
    List *list2 = [[List alloc] initWithTitle:@"我的手机" groups:l2];
    
    self.dataList = [NSMutableArray arrayWithObjects:list2, list1, nil];
}

@end

========================================

数据模型实现

// 好友数据对象
@interface Friend : NSObject

@property (nonatomic, retain) NSString *image;  // 头像
@property (nonatomic, retain) NSString *name;   // 昵称
@property (nonatomic, retain) NSString *state;  // 说说

@end

// 分组对象
@interface Group : NSObject

@property (nonatomic, assign) BOOL isDelop;             // 是否展开
@property (nonatomic, retain) NSString *title;          // 分组名称
@property (nonatomic, retain) NSString *detail;         // 在线状态
@property (nonatomic, retain) NSMutableArray *friends;  // 好友列表

@end

// 整个qq列表
@interface List : NSObject

@property (nonatomic, retain) NSString *title;          // 列表名称
@property (nonatomic, retain) NSMutableArray *groups;   // 列表内分组

@end

数据模型的构造方法就不贴上来了,实现部分每个类只有一个构造方法