您的位置:首页 > 产品设计 > UI/UE

iOS开发UI— QQ好友列表(处理头部控件的点击)viewForHeaderInSection:

2014-01-16 21:28 781 查看

1.实现效果及代码文件结果如下



2.具体实现(标准MVC)

2.1.View

//
//  MJHeaderView.m

#import "MJHeaderView.h"
#import "MJFriendGroup.h"

/**
某个控件出不来:
1.frame的尺寸和位置对不对

2.hidden是否为YES

3.有没有添加到父控件中

4.alpha 是否 < 0.01

5.被其他控件挡住了

6.父控件的前面5个情况
*/

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

@implementation MJHeaderView

+ (instancetype)headerViewWithTableView:(UITableView *)tableView
{
static NSString *ID = @"header";
MJHeaderView *header = [tableView dequeueReusableHeaderFooterViewWithIdentifier:ID];
if (header == nil) {
header = [[MJHeaderView alloc] initWithReuseIdentifier:ID];
}
return header;
}

/**
*  在这个初始化方法中,MJHeaderView的frame\bounds没有值
*/
- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
// 添加子控件
// 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];
// 设置按钮的内容左对齐
nameView.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
// 设置按钮的内边距
//        nameView.imageEdgeInsets
nameView.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
nameView.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
[nameView addTarget:self action:@selector(nameViewClick) forControlEvents:UIControlEventTouchUpInside];

// 设置按钮内部的imageView的内容模式为居中
nameView.imageView.contentMode = UIViewContentModeCenter;
// 超出边框的内容不需要裁剪
nameView.imageView.clipsToBounds = NO;

[self.contentView addSubview:nameView];
self.nameView = nameView;

// 2.添加好友数
UILabel *countView = [[UILabel alloc] init];
countView.textAlignment = NSTextAlignmentRight;
countView.textColor = [UIColor grayColor];
[self.contentView addSubview:countView];
self.countView = countView;
}
return self;
}

/**
*  当一个控件的frame发生改变的时候就会调用
*
*  一般在这里布局内部的子控件(设置子控件的frame)
*/
- (void)layoutSubviews
{
#warning 一定要调用super的方法
[super layoutSubviews];

// 1.设置按钮的frame
self.nameView.frame = self.bounds;

// 2.设置好友数的frame
CGFloat countY = 0;
CGFloat countH = self.frame.size.height;
CGFloat countW = 150;
CGFloat countX = self.frame.size.width - 10 - countW;
self.countView.frame = CGRectMake(countX, countY, countW, countH);
}

- (void)setGroup:(MJFriendGroup *)group
{
_group = group;

// 1.设置按钮文字(组名)
[self.nameView setTitle:group.name forState:UIControlStateNormal];

// 2.设置好友数(在线数/总数)
self.countView.text = [NSString stringWithFormat:@"%d/%d", group.online, group.friends.count];
}

/**
*  监听组名按钮的点击
*/
- (void)nameViewClick
{
// 1.修改组模型的标记(状态取反)
self.group.opened = !self.group.isOpened;

// 2.刷新表格
if ([self.delegate respondsToSelector:@selector(headerViewDidClickedNameView:)]) {
[self.delegate headerViewDidClickedNameView:self];
}
}

/**
*  当一个控件被添加到父控件中就会调用
*/
- (void)didMoveToSuperview
{
if (self.group.opened) {
self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
} else {
self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);
}
}

/**
*  当一个控件即将被添加到父控件中会调用
*/
//- (void)willMoveToSuperview:(UIView *)newSuperview
//{
//
//}
@end
//
//  MJFriendCell.m

#import "MJFriendCell.h"
#import "MJFriend.h"

@implementation MJFriendCell

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

- (void)setFriendData:(MJFriend *)friendData
{
_friendData = friendData;<pre name="code" class="objc">


2.2.Model

//
//  MJFriend.m

#import "MJFriend.h"

@implementation MJFriend
+ (instancetype)friendWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}

- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
@end


//
//  MJFriendGroup.m

#import "MJFriendGroup.h"
#import "MJFriend.h"

@implementation MJFriendGroup
+ (instancetype)groupWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}

- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
// 1.注入所有属性
[self setValuesForKeysWithDictionary:dict];

// 2.特殊处理friends属性
NSMutableArray *friendArray = [NSMutableArray array];
for (NSDictionary *dict in self.friends) {
MJFriend *friend = [MJFriend friendWithDict:dict];
[friendArray addObject:friend];
}
self.friends = friendArray;
}
return self;
}
@end

2.3 Controller

//
//  MJViewController.m

#import "MJViewController.h"
#import "MJFriendGroup.h"
#import "MJFriend.h"
#import "MJHeaderView.h"
#import "MJFriendCell.h"

@interface MJViewController () <MJHeaderViewDelegate>
@property (nonatomic, strong) NSArray *groups;
@end

@implementation MJViewController

- (void)viewDidLoad
{
[super viewDidLoad];

// 每一行cell的高度
self.tableView.rowHeight = 50;
// 每一组头部控件的高度
self.tableView.sectionHeaderHeight = 44;
}

- (NSArray *)groups
{
if (_groups == nil) {
NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"friends.plist" ofType:nil]];

NSMutableArray *groupArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
MJFriendGroup *group = [MJFriendGroup groupWithDict:dict];
[groupArray addObject:group];
}

_groups = groupArray;
}
return _groups;
}

- (BOOL)prefersStatusBarHidden
{
return YES;
}

#pragma mark - 数据源方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.groups.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
MJFriendGroup *group = self.groups[section];

return (group.isOpened ? group.friends.count : 0);
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.创建cell
MJFriendCell *cell = [MJFriendCell cellWithTableView:tableView];

// 2.设置cell的数据
MJFriendGroup *group = self.groups[indexPath.section];
cell.friendData = group.friends[indexPath.row];

return cell;
}

/**
*  返回每一组需要显示的头部标题(字符出纳)
*/
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// 1.创建头部控件
MJHeaderView *header = [MJHeaderView headerViewWithTableView:tableView];
header.delegate = self;

// 2.给header设置数据(给header传递模型)
header.group = self.groups[section];

return header;
}

#pragma mark - headerView的代理方法
/**
*  点击了headerView上面的名字按钮时就会调用
*/
- (void)headerViewDidClickedNameView:(MJHeaderView *)headerView
{
[self.tableView reloadData];
}
@end


3、实现思路整理

设置frame时的思路和一些注意点:
(1)
一个控件没有frame肯定显示不出来
设置frame的过程中需要从哪里入手呢?以后遇到要为很多控件设置frmae的时候。建议先找控件之间的关系,先找准一个固定不变的点,然后再计算不确定的控件的frmae.总要有一个点,再来计算其他的东西。
在这个应用中找到规律,先设置头像的,再设置其他的。
在真实开发中间隙等是由美工提供的。计算x,y,w,h等得值。分别计算所有控件的frame,注意这是依赖于数据的。

(2)
获取控件的最大值CGRectMaxX(SELF.ICONvIEW.FRAME)或取头像最大的x值。
在ios7中计算文字的宽度和高度?
需要传递一个字体。影响文本的宽度和高度的因素:(1)字体的大小;(2)存放文本的最大的范围。在计算文本的宽高时,应该告诉这两个。
_weibo.name sizewithFont:nil ios7以前的方法
ios7以后要传4个参数
boundingRectWthSize:(cgsize).....将来能够显示文本的范围,宽和高。
nsdictionary *dict=@{NSfontattributename:宏}
在创建昵称的时候就要告诉它,将来以15号的字体显示。(注意不要忘了这一点,否则计算出来的不准确)
不限制其宽度和高度的大小:MAXFLOAT
计算文本的宽高,把这个功能封装。接受三个参数,字符串,字体,Maxsize.返回值为CGSIZE.
需要计算的文本
文本显示的字体
文本显示的范围
文本占用的真实宽高。
注意:有关字体的计算,在创建的时候就要指定其将要显示的字号是多大。
内容文本的宽高和昵称不一样,正文会换行,那么就限制一下其宽度,不限制高度就可以了。
cell的高度不够,需要在viewdioad中设置cell的高度(大失所望)
默认label只显示一行。当创建正文的时候,还要设置让其自定换行。设置为0

(3)
如果没有配图的话就不计算它的宽高,把计算的过程放到if大括号里边。
设置配图的问题:有的又配图,有的没有配图(cell滚动离开视野放到缓存池中)。问题在于,如果需要一个没有配图的,这时候去缓存中去取,取到的是一个有配图的那不是就冲突了么?
如何解决这个问题:
在设置数据的时候进行判断,如果有配图,那么就设置数据,.hidden=no;
如果没有配图的话那就不让它显示。hidden=YES.
注意点:在tableview中有一个复用的问题,有显示就要有隐藏。这是一个陷阱。一定要记住。

(4)
所有的vip图标都是同一个,可以在init初始化方法中对vip图标进行设置。
此时出现了一个新的问题。所有的宽高计算一次就可以了,但是这里每次滚动都会调用计算,没有必要。

4、重要说明

IOS7以后计算文本的宽度和高度:

//4.设置正文的frame

CGFloat textLabX=iconViewX;

CGFloat textLabY=CGRectGetMaxY(self.iconView.frame)+padding;

CGSize textSize=[self sizeWithString:_weibo.text font:YYTextFont maxSize:CGSizeMake(300,MAXFLOAT)];

self.textLab.frame=CGRectMake(textLabX, textLabY, textSize.width, textSize.height);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐