QQ好友列表 (UITableViewHeaderFooterView的使用)

1,除可以为TableView设置Header/Footer文字外,还可以设置View,这个view如果是单独定义的CLASS,需要继承自UITableViewHeaderFooterView


2,当父控件的FRAME发生改变时,会自动调用子控件的layoutSubView方法,可重写此方法,对子控件进行重写布局,但此重写方法第一行必须先调用相同的父类方法

TableView中的三个数据源方法一旦确定,也就自动确定了每个section的头部/尾部FRAME,这里是自动改变的,可以在UITableViewHeaderFooterView中重写layoutSubView方法,这个方法也是自动调的


3,TableViewHeaderFooterView像TableViewCell一样可以被TableView自动放入到缓存池中进行回收利用,但relaodData方法是重写创建Cell或HeaderFooterView的,实际上是重写创建的,和旧的内存地址是不一样的;当一个控件被添加到父类中时,会自动调用:didMoveToSuperview




#import <UIKit/UIKit.h>


@class TXFriendGroup, TXFriendHeaderView;


@protocol TXFriendHeaderViewDelegate <NSObject>


@optional


- (void)friendHeaderViewDidClickedNameView:(TXFriendHeaderView *)headerView;


@end




@interface TXFriendHeaderView : UITableViewHeaderFooterView
@property (nonatomic, weak)  id<TXFriendHeaderViewDelegate> delegate;
@property (nonatomic, strong) TXFriendGroup *group;
+ (instancetype)friendHeaderViewWithTableView:(UITableView *)tableView;
@end

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

#import "TXFriendCell.h"
#import "TXFriend.h"


@implementation TXFriendCell


+ (instancetype)friendCellWithTableView:(UITableView *)tableView
{
    static NSString *ID = @"friendCell";
    TXFriendCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[TXFriendCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
    return cell;
}


- (void)setFriendData:(TXFriend *)friendData
{
    _friendData = friendData;
    
    self.imageView.image = [UIImage imageNamed:friendData.icon];
    
    self.textLabel.text = friendData.name;
    self.textLabel.textColor = friendData.isVip ? [UIColor redColor] : [UIColor blackColor];
    self.detailTextLabel.text = friendData.intro;
}




@end

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

#import "TXFriendHeaderView.h"
#import "TXFriendGroup.h"


@interface TXFriendHeaderView()


@property (nonatomic, weak)  UIButton *nameView;
@property (nonatomic, weak)  UILabel *countView;


@end


@implementation TXFriendHeaderView


+ (instancetype)friendHeaderViewWithTableView:(UITableView *)tableView
{
    static NSString *ID = @"friendGroup";
    TXFriendHeaderView *headerView = [tableView dequeueReusableCellWithIdentifier:ID];
    if (headerView == nil) {
        headerView = [[TXFriendHeaderView alloc] initWithReuseIdentifier:ID];
    }
    return headerView;
}


- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithReuseIdentifier:reuseIdentifier];
    if (self) {
        // 1
        UIButton *nameView = [UIButton buttonWithType:UIButtonTypeCustom];
        [nameView setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg"] forState:UIControlStateNormal];
        [nameView setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted];
        
        [nameView setImage:[UIImage imageNamed:@"buddy_header_arrow"] forState:UIControlStateNormal];
        [nameView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        
// Button内部有两个子控件,而控件一般是位于content中的,所以这里以conteng开头的水平对齐属性
        nameView.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
        nameView.imageEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
        nameView.titleEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0);
        
        nameView.imageView.contentMode = UIViewContentModeCenter;
        nameView.imageView.clipsToBounds = NO;
        
        
        [nameView addTarget:self action:@selector(nameViewClicked) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:nameView];
        self.nameView = nameView;
        
        // 2
        UILabel *countView = [[UILabel alloc] init];
// Label里面没有子控件了,直接写对齐属性
        countView.textAlignment = NSTextAlignmentRight;
        countView.textColor = [UIColor grayColor];
    
        [self.contentView addSubview:countView];
        self.countView = countView;
    }
    return self;
}
// 当父控件FRAME发生改变时,这个方法会被自动调用
// 父控件UITableHeaderFooterView 只要确定每一个组后,就会被自动放到每个section组的头部或尾部,这样他的FRAME就被改变了
- (void)layoutSubviews
{
    [super layoutSubviews]; // 必须先调用父类的方法
    
    self.nameView.frame = self.bounds;
    
    CGFloat countW = 100;
    CGFloat countH = self.bounds.size.height;
    CGFloat countX = self.bounds.size.width - countW - 5;
    CGFloat countY = 0;
    self.countView.frame = CGRectMake(countX, countY, countW, countH);
    
    [self didMoveToSuperview];//缓存池中取出的headerView可能那个三角形按钮是以前旧状态,所以再次调用一次检查
}


// 当前控件被添加到父控件时,就会自动调用下面的方面
- (void)didMoveToSuperview
{
    if (self.group.isOpened) {
        self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
    } else {
        self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);
    }
}


- (void)setGroup:(TXFriendGroup *)group
{
    _group = group;
    [self.nameView setTitle:group.name forState:UIControlStateNormal];
    
    self.countView.text = [NSString stringWithFormat:@"%@/%d ", group.online, group.friends.count];
}


- (void)nameViewClicked
{
    self.group.opened = !self.group.isOpened;
    
    if ([self.delegate respondsToSelector:@selector(friendHeaderViewDidClickedNameView:)]) {
        [self.delegate friendHeaderViewDidClickedNameView:self];
    }
}


@end

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

#import "TXViewController.h"
#import "TXFriendGroup.h"
#import "TXFriendCell.h"
#import "TXFriendHeaderView.h"


@interface TXViewController () <TXFriendHeaderViewDelegate>




@property (nonatomic, strong) NSArray *groups;
@property (weak, nonatomic) IBOutlet UITableView *myTableView;


@end


@implementation TXViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    self.myTableView.rowHeight = 50;
    
    self.myTableView.sectionHeaderHeight = 44;
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return self.groups.count;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    TXFriendGroup *group = self.groups[section];
    return group.isOpened ? group.friends.count : 0; // 子Cell关闭/显示 效果,其实就是控制组内部row的行数后,再刷新table
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    TXFriendCell *cell = [TXFriendCell friendCellWithTableView:tableView];
    
    TXFriendGroup *group = self.groups[indexPath.section];
    
    cell.friendData = group.friends[indexPath.row];
    
    return cell;
}


- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    TXFriendHeaderView *headerView = [TXFriendHeaderView friendHeaderViewWithTableView:tableView];
    
    headerView.group = self.groups[section];
    headerView.delegate = self;
    
    return headerView;
}


- (void)friendHeaderViewDidClickedNameView:(TXFriendHeaderView *)headerView
{
    [self.myTableView reloadData];
}


- (NSArray *)groups
{
    if(_groups == nil)
    {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"friends.plist" ofType:nil];
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
        
        NSMutableArray *groupArray = [NSMutableArray array];
        for (NSDictionary *dict in dictArray) {
            TXFriendGroup *group = [TXFriendGroup groupWithDict:dict];
            [groupArray addObject:group];
        }
        _groups = groupArray;
    }
    return _groups;
}


- (BOOL)prefersStatusBarHidden
{
    return YES;
}


@end

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

#import <UIKit/UIKit.h>
@class TXFriend;


@interface TXFriendCell : UITableViewCell


@property (nonatomic, strong) TXFriend *friendData;


+ (instancetype)friendCellWithTableView:(UITableView *)tableView;
@end


展开阅读全文

没有更多推荐了,返回首页