iOS开发 --UITableviewCell的自定义与计算frame

一、UITableViewCell简介

UITableView上的每一行的内容都是UITableViewCell来显示的,通过 UITableViewDataSource的协议方法:tableView:cellForRowAtIndexPath:来初始化要显示的内容。而 UITableViewCell则是通过它自带的contentView来显示,每个Cell都默认有个子视图contentView,所以每个cell 上显示的内容都是加在这个视图上。

系统的UITableViewCell有四种类型

  UITableViewCellStyleDefault,  
    UITableViewCellStyleValue1,     
    UITableViewCellStyleValue2,       
    UITableViewCellStyleSubtitle

这四种类型自己尝试一下看看有什么不同,开发一般很少会用的到,因为系统的满足不了我们的需求,所以我们经常会自定义UITableViewCell

UITableView的一些属于:

有时候我们会发现很多UITableViewCell右侧可以显示不同的图标,在iOS中称之为访问器,点击可以触发不同的事件,例如iPhone系统的设置

要设置这些图标只需要设置UITableViewCell的accesoryType属性,accesoryType是一个枚举类型,有以下几种类型:

typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) {
    UITableViewCellAccessoryNone,                   // 不显示任何图标
    UITableViewCellAccessoryDisclosureIndicator,    // 跳转指示图标
    UITableViewCellAccessoryDetailDisclosureButton, // 内容详情图标和跳转指示图标
    UITableViewCellAccessoryCheckmark,              // 勾选图标
    UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0) // 内容详情图标
};

但是,你会发现没有第一个cell的accesoryType没有这种类型,其实只要设置UITableViewCell的accessoryView就可以让你的cell显示你想要的控件,只要是一个UIView都能支持

二、如何自定义UITableViewCell

1.首先要知道你想要显示怎么样的cell

2.将你需要显示的控件都定义成属性

3.因为开发的时候给cell赋值时一般都是有对应的model,所以最好写一个方法专门给cell赋值

4.因为我们自定义cell的时候可能会有很多控件,可以写一个类来计算这些控件的frame,然后写一个方法来给这些控件设置frame,最后可以在调用给cell赋值方法的时候一起调用这个方法

这里我简单的模仿一下QQ好友动态的frame的计算

#import <Foundation/Foundation.h>

@interface MZQQModel : NSObject

@property (nonatomic,copy) NSString *text;
@property (nonatomic,copy) NSString *icon;
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *picture;
@property (nonatomic,copy) NSString *time;
@property (nonatomic,copy) NSString *expert;

@end

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

@interface MZQQFrame : NSObject

@property (nonatomic, strong) MZQQModel *qqModel;

@property (nonatomic, assign, readonly) CGRect iconFrame; // 头像的frame
@property (nonatomic, assign, readonly) CGRect nameFrame; // 昵称的frame
@property (nonatomic, assign, readonly) CGRect timeFrame; // 时间的frame
@property (nonatomic, assign, readonly) CGRect expertFrame; // QQ达人的Frame
@property (nonatomic, assign, readonly) CGRect textFrame; // 正文的Frame
@property (nonatomic, assign, readonly) CGRect pictureFrame; // 图片的Frame

@property (nonatomic, assign, readonly) CGFloat rowHeight; // 总得高度

@end

#import "MZQQFrame.h"
#import "MZQQModel.h"

#define MZNameFont 15 // 昵称字体的大小
#define MZTextFont 14 // 内容字体的大小
#define kScreenWidth [UIScreen mainScreen].bounds.size.width

@implementation MZQQFrame

//计算文字的大小
- (CGSize)sizeWithText:(NSString *)text maxSize:(CGSize)maxSize fontSize:(CGFloat)fontSize
{
    //计算文本的大小
    CGSize nameSize = [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil].size;
    return nameSize;
}

- (void)setQqModel:(MZQQModel *)qqModel{

    _qqModel = qqModel;

    CGFloat margin = 10;
    //头像
    CGFloat iconW = 40;
    CGFloat iconH = 40;
    CGFloat iconX = margin;
    CGFloat iconY = margin;
    _iconFrame = CGRectMake(iconX, iconY, iconW, iconH);
    //昵称
    CGSize nameSize = [self sizeWithText:self.qqModel.name maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT) fontSize:MZNameFont];
    CGFloat nameX = CGRectGetMaxX(_iconFrame) + margin;
    CGFloat nameY = iconY;
    _nameFrame = CGRectMake(nameX, nameY, nameSize.width, nameSize.height);
    //时间
    CGSize timeSize = [self sizeWithText:self.qqModel.time maxSize:CGSizeMake(kScreenWidth - CGRectGetMidX(_pictureFrame), MAXFLOAT) fontSize:12];
    CGFloat timeX = nameX;
    CGFloat timeY = CGRectGetMaxY(_nameFrame) + margin;
    _timeFrame = CGRectMake(timeX, timeY, timeSize.width, timeSize.height);
    //达人
    CGFloat expertW = 14;
    CGFloat expertH = 14;
    CGFloat expertY = nameY;
    CGFloat expertX = CGRectGetMaxX(_nameFrame) + margin;
    _expertFrame = CGRectMake(expertX, expertY, expertW, expertH);
    //QQ内容
    CGSize textSize = [self sizeWithText:self.qqModel.text maxSize:CGSizeMake(kScreenWidth - 2 * margin, MAXFLOAT) fontSize:MZTextFont];
    CGFloat textX = iconX;
    CGFloat textY = CGRectGetMaxY(_iconFrame) + margin;
    _textFrame = CGRectMake(textX, textY, textSize.width, textSize.height);

    //QQ图片 (这里的图片大小给定了100,实际根据自己需求调整)
    if (self.qqModel.picture) {
        CGFloat pictureW = 100;
        CGFloat pictureH = 100;
        CGFloat pictureX = iconX;
        CGFloat pictureY = CGRectGetMaxY(_textFrame) + margin;
        _pictureFrame = (CGRect){{pictureX,pictureY},{pictureW,pictureH}};

        _rowHeight = CGRectGetMaxY(_pictureFrame) + margin;
    }else{
        _rowHeight = CGRectGetMaxY(_textFrame) + margin;
    }

}

@end

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

@interface MZQQCell : UITableViewCell

@property (nonatomic, strong) MZQQFrame *qqFrame;

@end

#import "MZQQCell.h"
#import "MZQQFrame.h"
#import "MZQQModel.h"

@interface MZQQCell ()

@property (nonatomic, strong) UIImageView *iconView; // 头像
@property (nonatomic, strong) UILabel *nameView; // 昵称
@property (nonatomic, strong) UILabel *timeView; // 时间
@property (nonatomic, strong) UIImageView *expertView; // 达人
@property (nonatomic, strong) UILabel *textView; // 正文
@property (nonatomic, strong) UIImageView *pictureView; // 图片

@end

@implementation MZQQCell

- (UIImageView *)iconView{
    if (!_iconView) {
        _iconView = [[UIImageView alloc] init];
    }
    return _iconView;
}

- (UILabel *)nameView{
    if (!_nameView) {
        _nameView = [[UILabel alloc] init];
    }
    return _nameView;
}

- (UILabel *)timeView{
    if (!_timeView) {
        _timeView = [[UILabel alloc] init];
    }
    return _timeView;
}

- (UIImageView *)expertView{
    if (!_expertView) {
        _expertView = [[UIImageView alloc] init];
    }
    return _expertView;
}

- (UILabel *)textView{
    if (!_textView) {
        _textView = [[UILabel alloc] init];
    }
    return _textView;
}

- (UIImageView *)pictureView{
    if (!_pictureView) {
        _pictureView = [[UIImageView alloc] init];
    }
    return _pictureView;
}

- (void)setQqFrame:(MZQQFrame *)qqFrame{

    _qqFrame = qqFrame;
    //设置子控件显示的内容
    [self setSubViewsContent];
    //设置子控件的frame
    [self setSubViewsFrame];

}

- (void)setSubViewsContent{

    MZQQModel *qqModel = self.qqFrame.qqModel;
    self.iconView.image = [UIImage imageNamed:qqModel.icon];
    self.nameView.text = qqModel.name;
    self.timeView.text = qqModel.time;

    // 如果qqModel.expert有值给图片
    if (qqModel.expert) {
        self.expertView.hidden = NO;
        self.expertView.image = [UIImage imageNamed:qqModel.expert];
    }else{
        self.expertView.hidden = YES;
    }
    if (_pictureView) {
        self.pictureView.image = [UIImage imageNamed:qqModel.picture];
    }
}

- (void)setSubViewsFrame{

    self.iconView.frame = self.qqFrame.iconFrame;
    self.nameView.frame = self.qqFrame.nameFrame;
    self.timeView.frame = self.qqFrame.timeFrame;
    self.expertView.frame = self.qqFrame.expertFrame;
    self.textView.frame = self.qqFrame.textFrame;
    self.pictureView.frame = self.qqFrame.pictureFrame;

}

上面都是一些计算frame的方法

其实计算frame并不是很难,只要你确定第一个控件的位置,你就可以根据第一个控件将其它控件的frame一一计算出来

当然,cell还有很多属性和方法,有兴趣的可以自己去研究研究

时间: 2024-12-21 13:06:06

iOS开发 --UITableviewCell的自定义与计算frame的相关文章

iOS开发UI篇—自定义瀑布流控件(基本实现)

iOS开发UI篇—自定义瀑布流控件(基本实现) 一.基本实现 说明:在View加载的时候,刷新数据. 1.实现代码 YYViewController.m文件 1 // 2 // YYViewController.m 3 // 06-瀑布流 4 // 5 // Created by apple on 14-7-28. 6 // Copyright (c) 2014年 wendingding. All rights reserved. 7 // 8 9 #import "YYViewControll

iOS开发UI篇—自定义瀑布流控件(蘑菇街数据刷新操作)

iOS开发UI篇—自定义瀑布流控件(蘑菇街数据刷新操作) 一.简单说明 使用数据刷新框架: 该框架提供了两种刷新的方法,一个是使用block回调(存在循环引用问题,_ _weak),一个是使用调用. 问题:在进行下拉刷新之前,应该要清空之前的所有数据(在刷新数据这个方法中). 移除正在显示的cell: (1)把字典中的所有的值,都从屏幕上移除 (2)清除字典中的所有元素 (3)清除cell的frame,每个位置的cell的frame都要重新计算 (4)清除可复用的缓存池. 该部分的代码如下: 1

iOS开发UITableViewCell的选中时的颜色设置

1.系统默认的颜色设置 //无色 cell.selectionStyle = UITableViewCellSelectionStyleNone; //蓝色 cell.selectionStyle = UITableViewCellSelectionStyleBlue; //灰色 cell.selectionStyle = UITableViewCellSelectionStyleGray; 2.自定义颜色和背景设置 改变UITableViewCell选中时背景色: UIColor *color

iOS开发UI篇—自定义瀑布流控件(蘑菇街实现)

iOS开发UI篇—自定义瀑布流控件(蘑菇街瀑布流) 一.简单说明 关于瀑布流 1.是使用UIScrollView实现的 2.刷新数据(reloadData)方法里面做哪些事情 3.layoutSubviews方法里面做哪些事情 4.模仿UItableView进行设计 完善: 瀑布流控件第一次显示到屏幕上的时候自动的向数据源索要数据,而不需要手动调用.这需要监听View的显示,View的显示有一个方法,叫做willMoveToSuperview:在该方法中直接刷新一次数据即可. 二.把自定义的瀑布

iOS开发UI篇—自定义瀑布流控件(cell的循环利用)

iOS开发UI篇—自定义瀑布流控件(cell的循环利用) 一.简单说明 当滚动的时候,向数据源要cell. 当UIScrollView滚动的时候会调用layoutSubviews在tableView中也是一样的,因此,可以用这个方法来监听scrollView的滚动,可以在在这个地方向数据源索要对应位置的cell(frame在屏幕上的cell). 示例: 当scrollView在屏幕上滚动的时候,离开屏幕的cell应该放到缓存池中去,询问即将(已经)进入到屏幕的cell,对于还没有进入到屏幕的ce

iOS开发多线程之自定义NSOperation

iOS开发多线程篇—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UITableViewController. 1 // 2 // YYViewController.h 3 // 01-自定义Operation 4 // 5 // Created by apple on 14-6-26. 6 // Copyright (c) 2014年 itcase. All rig

iOS开发多线程篇—自定义NSOperation

iOS开发多线程篇—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UITableViewController. 1 // 2 // YYViewController.h 3 // 01-自定义Operation 4 // 5 // Created by apple on 14-6-26. 6 // Copyright (c) 2014年 itcase. All rig

iOS开发UI篇—九宫格坐标计算

iOS开发UI篇—九宫格坐标计算 一.要求 完成下面的布局 二.分析 寻找左边的规律,每一个uiview的x坐标和y坐标. 三.实现思路 (1)明确每一块用得是什么view (2)明确每个view之间的父子关系,每个视图都只有一个父视图,拥有很多的子视图. (3)可以先尝试逐个的添加格子,最后考虑使用for循环,完成所有uiview的创建 (4)加载app数据,根据数据长度创建对应个数的格子 (5)添加格子内部的子控件 (6)给内部的子控件装配数据 四.代码示例 // // YYViewCont

iOS开发UI基础—九宫格坐标计算

iOS开发UI基础-九宫格坐标计算 一.要求 完成下面的布局 二.分析 寻找左边的规律,每一个uiview的x坐标和y坐标. 三.实现思路 (1)明确每一块用得是什么view (2)明确每个view之间的父子关系,每个视图都只有一个父视图,拥有很多的子视图. (3)可以先尝试逐个的添加格子,最后考虑使用for循环,完成所有uiview的创建 (4)加载app数据,根据数据长度创建对应个数的格子 (5)添加格子内部的子控件 (6)给内部的子控件装配数据 四.代码示例 1 // 2 // YYVie