zoukankan      html  css  js  c++  java
  • UI基础--UITableView实现仿QQ好友列表页面

    需求:类似于QQ好友列表页面的显示,有好友分组,有好友数量,在线人数,vip会员、展开分组时显示分组好友,合并分组时不显示:具体效果图如下:

    分析:

    1、展开分组时显示分组好友,该功能可以使用显示UITableViewCell的数据即可;

    2、分组头可以考虑使用一个headerView来实现;

    示例文件结构:

    具体实现步骤:

    1、自定义数据模型类,由于plist文件中包含了2个字典,所以需要写2个数据模型;

    2、自定义cell属性包括数据模型以及生成可重用cell的方法,由于系统自带的子控件即可满足实际要求,所以不用写frame模型了;

    4、自定义HeaderView,包括模型数据属性和快速构造HeaderView的类方法,以及代理方法;

    5、在控制器中写UITableView的 数据显示的方法;

     

    具体代码:

    Model:

     

     1 //
     2 //  JWFriend.h
     3 //  12-24-FriendGroup
     4 //
     5 //  Created by xiaomoge on 14/12/24.
     6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 
    11 @interface JWFriend : NSObject
    12 @property (nonatomic,copy) NSString *icon;
    13 @property (nonatomic,copy) NSString *intro;
    14 @property (nonatomic,copy) NSString *name;
    15 @property (nonatomic,assign,getter=isVip) BOOL vip;
    16 - (instancetype)initWithDic:(NSDictionary *)dic;
    17 + (instancetype)friendWithDic:(NSDictionary *)dic;
    18 @end

     

     1 //
     2 //  JWFriend.m
     3 //  12-24-FriendGroup
     4 //
     5 //  Created by xiaomoge on 14/12/24.
     6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import "JWFriend.h"
    10 
    11 @implementation JWFriend
    12 - (instancetype)initWithDic:(NSDictionary *)dic {
    13     if (self = [super init]) {
    14         [self setValuesForKeysWithDictionary:dic];//KVC的使用
    15     }
    16     return self;
    17 }
    18 + (instancetype)friendWithDic:(NSDictionary *)dic {
    19     return [[self alloc] initWithDic:dic];
    20 }
    21 @end
     1 //
     2 //  JWFriendGroup.h
     3 //  12-24-FriendGroup
     4 //
     5 //  Created by xiaomoge on 14/12/24.
     6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 
    11 @interface JWFriendGroup : NSObject
    12 @property (nonatomic,strong) NSArray *friends;
    13 @property (nonatomic,copy) NSString *name;
    14 @property (nonatomic,assign) int online;
    15 /*
    16  组头是否展开,默认为NO
    17  */
    18 @property (nonatomic,assign,getter=isExpend) BOOL expend;
    19 - (instancetype)initWithDic:(NSDictionary *)dic;
    20 + (instancetype)friendGroupWithDic:(NSDictionary *)dic;
    21 + (NSMutableArray *)friendGroupList;
    22 @end
     1 //
     2 //  JWFriendGroup.m
     3 //  12-24-FriendGroup
     4 //
     5 //  Created by xiaomoge on 14/12/24.
     6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import "JWFriendGroup.h"
    10 #import "JWFriend.h"
    11 @implementation JWFriendGroup
    12 - (instancetype)initWithDic:(NSDictionary *)dic {
    13     if (self = [super init]) {
    14         [self setValuesForKeysWithDictionary:dic];
    15     }
    16     return self;
    17 }
    18 + (instancetype)friendGroupWithDic:(NSDictionary *)dic {
    19     return [[self alloc] initWithDic:dic];
    20 }
    21 
    22 + (NSMutableArray *)friendGroupList {
    23     NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"friends" ofType:@"plist"]];
    24     
    25     NSMutableArray *tempArray = [NSMutableArray array];
    26     
    27     for (NSDictionary *dic in array) {//字典转模型
    28         JWFriendGroup *friendGroup = [JWFriendGroup friendGroupWithDic:dic];
    29         
    30         NSMutableArray *tem = [NSMutableArray array];
    31         for (NSDictionary *dict in friendGroup.friends) {//模型里面还带有子弹,所以继续进行字典转模型步骤
    32             JWFriend *friend = [JWFriend friendWithDic:dict];
    33             [tem addObject:friend];
    34         }
    35         friendGroup.friends = tem;//转完模型后记得重新赋值
    36         [tempArray addObject:friendGroup];
    37     }
    38     return tempArray;
    39 }
    40 @end

    View:

     1 //
     2 //  JWFriendCell.h
     3 //  12-24-FriendGroup
     4 //
     5 //  Created by xiaomoge on 14/12/24.
     6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import <UIKit/UIKit.h>
    10 @class JWFriend;
    11 @interface JWFriendCell : UITableViewCell
    12 @property (nonatomic,strong) JWFriend *friendDatas;
    13 + (instancetype)cellWithTableView:(UITableView *)tableView;
    14 @end
     1 //
     2 //  JWFriendCell.m
     3 //  12-24-FriendGroup
     4 //
     5 //  Created by xiaomoge on 14/12/24.
     6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import "JWFriendCell.h"
    10 #import "JWFriend.h"
    11 @implementation JWFriendCell
    12 //快速构造一个可重用的cee
    13 + (instancetype)cellWithTableView:(UITableView *)tableView {
    14     static NSString *resue = @"cell";
    15     JWFriendCell *cell = [tableView dequeueReusableCellWithIdentifier:resue];
    16     if (!cell) {
    17         cell = [[self alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:resue];
    18     }
    19     return cell;
    20 }
    21 //重写set方法,给各子控件赋值
    22 - (void)setFriendDatas:(JWFriend *)friendDatas {
    23     _friendDatas = friendDatas;
    24     self.textLabel.text = friendDatas.name;
    25     self.detailTextLabel.text = friendDatas.intro;
    26     self.imageView.image = [UIImage imageNamed:friendDatas.icon];
    27     self.textLabel.textColor = friendDatas.isVip ? [UIColor redColor] : [UIColor blackColor];//如果是vip,那么呢称字体为红色
    28 }
    29 @end
     1 //
     2 //  JWFriendHeaderView.h
     3 //  12-24-FriendGroup
     4 //
     5 //  Created by xiaomoge on 14/12/24.
     6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import <UIKit/UIKit.h>
    10 @class JWFriendGroup,JWFriendHeaderView;
    11 @protocol JWFriendHeaderViewDelegate <NSObject>
    12 @optional
    13 - (void)clickNameBtn:(JWFriendHeaderView *)headerView;
    14 
    15 @end
    16 @interface JWFriendHeaderView : UITableViewHeaderFooterView
    17 @property (nonatomic,strong) JWFriendGroup *friendGroup;
    18 @property (nonatomic,assign) id<JWFriendHeaderViewDelegate> delegate;
    19 + (instancetype)headerViewWithTableView:(UITableView *)tableView;
    20 @end
     1 //
     2 //  JWFriendHeaderView.m
     3 //  12-24-FriendGroup
     4 //
     5 //  Created by xiaomoge on 14/12/24.
     6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import "JWFriendHeaderView.h"
    10 #import "JWFriendGroup.h"
    11 @interface JWFriendHeaderView ()
    12 @property (nonatomic,weak) UIButton *nameView;
    13 @property (nonatomic,weak) UILabel *countLabel;
    14 @end
    15 @implementation JWFriendHeaderView
    16 //快速构造一个可重用的组头
    17 + (instancetype)headerViewWithTableView:(UITableView *)tableView {
    18     static NSString *resue = @"head";//缓存池标识
    19     JWFriendHeaderView *headerView = [tableView dequeueReusableCellWithIdentifier:resue];
    20     if (!headerView) {
    21         headerView = [[self alloc] initWithReuseIdentifier:resue];
    22     }
    23     return headerView;
    24 }
    25 //重写方法,初始化控件
    26 - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier {
    27     if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
    28         UIButton *nameBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    29         [self.contentView addSubview:nameBtn];
    30         self.nameView = nameBtn;
    31         //按钮的一些属性的设置
    32         [nameBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    33         [nameBtn setImage:[UIImage imageNamed:@"buddy_header_arrow"] forState:UIControlStateNormal];
    34         [nameBtn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg"] forState:UIControlStateNormal];
    35         [nameBtn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted];
    36         nameBtn.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);//按钮内容的间距,左间距为10
    37         nameBtn.titleEdgeInsets =  UIEdgeInsetsMake(0, 10, 0, 0);//文字内容的间距,左间距为10
    38         nameBtn.imageView.contentMode = UIViewContentModeCenter;//不缩放按钮图片
    39         nameBtn.imageView.clipsToBounds = NO;//图片超出部分不裁剪
    40         nameBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;//设置左对齐
    41         [nameBtn addTarget:self action:@selector(nameClick) forControlEvents:UIControlEventTouchUpInside];//注册按钮点击事件
    42         
    43         UILabel *countLabel  = [[UILabel alloc] init];
    44         [self.contentView addSubview:countLabel];
    45         self.countLabel = countLabel;
    46         //文本标签的一些属性的设置
    47         countLabel.textAlignment = NSTextAlignmentRight;
    48         countLabel.font = [UIFont systemFontOfSize:14];
    49         countLabel.textColor = [UIColor grayColor];
    50     }
    51     return self;
    52 }
    53 //这个方法改变了组头的frame后就会调用,那么可以在这里设置frame了
    54 - (void)layoutSubviews {
    55     [super layoutSubviews];//记得必须先实现父类的该方法
    56     self.nameView.frame = self.bounds;
    57     CGFloat countX = self.bounds.size.width - 10 - 150;
    58     self.countLabel.frame = CGRectMake(countX, 0, 150, 44);
    59 }
    60 //点击组头按钮事件
    61 - (void)nameClick {
    62     self.friendGroup.expend = !self.friendGroup.isExpend;//获取组头是否展开状态
    63     [self expend];//调用封装的一个方法,如果展开,那么图片旋转90度,否则不展开
    64     if ([self.delegate respondsToSelector:@selector(clickNameBtn:)]) {//通知代理,点击了组头按钮
    65         [self.delegate clickNameBtn:self];
    66     }
    67 }
    68 //重写set方法,给各控件赋值
    69 - (void)setFriendGroup:(JWFriendGroup *)friendGroup {
    70     _friendGroup = friendGroup;//这句记得写,否则会造成没有内容显示
    71     [self.nameView setTitle:friendGroup.name forState:UIControlStateNormal];
    72     self.countLabel.text = [NSString stringWithFormat:@"%d/%lu",friendGroup.online,(unsigned long)friendGroup.friends.count];
    73     [self expend];//调用封装的一个方法,如果展开,那么图片旋转90度,否则不展开
    74 }
    75 //封装的方法,如果展开,那么图片旋转90度,否则旋转度为0
    76 - (void)expend {
    77     CGFloat angle = self.friendGroup.isExpend ? M_PI_2 : 0;
    78     [UIView animateWithDuration:0.5 animations:^{
    79         self.nameView.imageView.transform = CGAffineTransformMakeRotation(angle);
    80     }];
    81 }
    82 @end

    Controller:

     1 //
     2 //  ViewController.m
     3 //  12-24-FriendGroup
     4 //
     5 //  Created by xiaomoge on 14/12/24.
     6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 #import "JWFriend.h"
    11 #import "JWFriendGroup.h"
    12 #import "JWFriendHeaderView.h"
    13 #import "JWFriendCell.h"
    14 @interface ViewController () <JWFriendHeaderViewDelegate>
    15 @property (nonatomic,strong) NSArray *friendGroup;
    16 @end
    17 
    18 @implementation ViewController
    19 #pragma mark - 隐藏状态栏
    20 - (BOOL)prefersStatusBarHidden {
    21     return YES;
    22 }
    23 #pragma mark - 懒加载
    24 - (NSArray *)friendGroup {
    25     if (!_friendGroup) {
    26         _friendGroup = [JWFriendGroup friendGroupList];
    27     }
    28     return _friendGroup;
    29 }
    30 - (void)viewDidLoad {
    31     [super viewDidLoad];
    32     //设置组头的高度
    33     self.tableView.sectionHeaderHeight = 44;
    34 }
    35 #pragma mark - tableViewDatasouce的方法
    36 //显示多少组数据
    37 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    38     return self.friendGroup.count;
    39 }
    40 //每组数据显示多少行数据
    41 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    42     return [self.friendGroup[section] isExpend ]?[self.friendGroup[section] friends].count : 0;//这里使用了三目运算符,主要是判断如果组头是展开的,那么显示行数据,否则显示为0
    43 }
    44 //显示每个cell的内容
    45 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    46     JWFriendCell *cell = [JWFriendCell cellWithTableView:tableView];
    47     cell.friendDatas = [self.friendGroup[indexPath.section] friends][indexPath.row];
    48     return cell;
    49 }
    50 #pragma mark - JWFriendHeaderView的方法
    51 //显示组头view的内容
    52 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    53     JWFriendHeaderView *headerView = [JWFriendHeaderView headerViewWithTableView:tableView];
    54     headerView.friendGroup = self.friendGroup[section];
    55     headerView.delegate = self;
    56     headerView.tag = section;//把section赋值给组头的tag
    57     return headerView;
    58 }
    59 #pragma mark - JWFriendHeaderViewDelegate的方法
    60 - (void)clickNameBtn:(JWFriendHeaderView *)headerView {
    61     NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:headerView.tag];
    62     [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone];//判断点击的是哪个组头,然后加载对应的数据
    63 }
    64 @end

     

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    基于分布式锁解决定时任务重复问题
    基于Redis的Setnx实现分布式锁
    基于数据库悲观锁的分布式锁
    使用锁解决电商中的超卖
  • 原文地址:https://www.cnblogs.com/xiaomoge/p/4200599.html
Copyright © 2011-2022 走看看