iOS学习之UI自定义cell
一、自定义Cell
- 为什么需要自定义cell:系统提供的cell满足不了复杂的样式,因此:自定义Cell和自定义视图一样,自己创建一种符合我们需求的Cell并使用这个Cell。如下图所示的这些Cell都是通过自定义Cell样式实现的:
- 自定义Cell的步骤:
1.首先创建一个继承于UITableViewCell的类:(这是一个简易的通讯录的自定义cell)
- @interface RootTableViewCell : UITableViewCell
- // 联系人头像
- @property (nonatomic, strong) UIImageView *headerImageView;
- // 联系人姓名label
- @property (nonatomic, strong) UILabel *nameLabel;
- // 电话号码的label
- @property (nonatomic, strong) UILabel *phoneLabel;
- @end
2.实现UITableViewCell的初始化方法:
- @implementation RootTableViewCell
- - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- {
- self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
- if (self) {
- // 初始化子视图
- [self initLayout];
- }
- return self;
- }
- - (void)initLayout
- {
- // 1.头像
- self.headerImageView = [[UIImageView alloc] initWithFrame:CGRectMake(, , , )];
- // self.headerImageView.backgroundColor = [UIColor orangeColor];
- self.headerImageView.layer.masksToBounds = YES;
- self.headerImageView.layer.cornerRadius = ;
- // cell提供了一个contentView的属性,专门用来自定义cell,防止在cell布局的时候发生布局混乱,如果是自定义cell,记得将子控件添加到ContentView上
- [self.contentView addSubview:self.headerImageView];
- // 2.姓名
- self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.headerImageView.frame) + , CGRectGetMinY(self.headerImageView.frame), , )];
- // self.nameLabel.backgroundColor = [UIColor redColor];
- [self.contentView addSubview:self.nameLabel];
- // 3.电话号码
- self.phoneLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.nameLabel.frame), CGRectGetMaxY(self.nameLabel.frame) + , , )];
- // self.phoneLabel.backgroundColor = [UIColor greenColor];
- [self.contentView addSubview:self.phoneLabel];
- }
- 注意:
- 确保所有的你想添加的子视图都在自定义Cell的初始化方法中创建,由于UITableView的重用机制,一个Cell在第一次创建成功并用于下一次显示的时候,不会再走初始化方法,这样可以避免子视图的重复创建。
- 在Cell的子视图创建成功后,将子视图设置为属性,类似于UITableViewCell所自带的textLabel和detailTextLabel属性。便于在UITableView的协议中给自定义视图赋值。
二、Model类型对象的使用
- Model类概述:
- Model类主要是为了给我们提供数据,简单的说即自定义类且继承于NSObject的称之为Model。(前面OC学到的KVC就是帮助我们将字典转换为Model类。)
- 在自定义Cell中使用Model类存放数据:
- 首先创建Model类并继承于NSObject
- 然后添加和字典中对应的属性
- 在视图控制器中将字典通过KVC为Model赋值
- 将Model对象添加到数组中并刷新TableView
- // 建立model存放数据
- @interface Contact : NSObject
- // 姓名
- @property (nonatomic, copy) NSString *name;
- // 手机号码
- @property (nonatomic, copy) NSString *phoneNumber;
- // 图片名
- @property (nonatomic, copy) NSString *imageName;
- @end
- #import "RootTableViewController.h"
- #import "Contact.h"
- #import "RootTableViewCell.h"
- @interface RootTableViewController ()
- // 声明一个大数组存放所有联系人
- @property (nonatomic, strong) NSMutableArray *allContactsArray;
- @end
- @implementation RootTableViewController
- // 懒加载 (重写getter方法)
- - (NSMutableArray *)allContactsArray
- {
- if (_allContactsArray == nil) {
- _allContactsArray = [NSMutableArray array];
- }
- return _allContactsArray;
- }
- - (void)viewDidLoad {
- [super viewDidLoad];
- self.title = @"通讯录";
- self.navigationController.navigationBar.barTintColor = [UIColor lightGrayColor];
- [self handleData];
- }
- - (void)handleData
- {
- // 读取plist文件
- NSMutableArray *array =[NSMutableArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Contacts" ofType:@"plist"]];
- // 将要显示的数据转为model对象
- for (NSDictionary *contactDict in array) {
- Contact *contact = [[Contact alloc] init];
- // 使用KVC赋值
- [contact setValuesForKeysWithDictionary:contactDict];
- // 将联系人model存放在大数组中
- [self.allContactsArray addObject:contact];
- }
- }
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- }
- #pragma mark - Table view data source
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- return self.allContactsArray.count;
- }
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- ;
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- // 创建常量标识符
- static NSString *identifier = @"cell";
- // 从重用队列里查找可重用的cell
- RootTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
- // 判断如果没有可以重用的cell,创建
- if (!cell) {
- cell = [[RootTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
- }
- // 设置数据
- // 取出model对象
- Contact *contact = self.allContactsArray[indexPath.section];
- cell.headerImageView.image = [UIImage imageNamed:contact.imageName];
- cell.nameLabel.text = contact.name;
- cell.phoneLabel.text = contact.phoneNumber;
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- return cell;
- }
- - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- ;
- }
- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- {
- [tableView deselectRowAtIndexPath:indexPath animated:YES];
- }
- @end
3.运行效果如下图:
三、多种Cell混合使用
- 一个重用标识符只能针对于一种Cell样式,不同的Cell需要基于不同的重用标识符来进行区分,而重用标识符的区分需要根据不同的情况来划分,比如:
- model属性划分(不同的数据内容,比如一个数据中有type字段,为1代表图片类型,为0代表文字类型等)
- 固定的行显示的Cell类型不一样
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- static NSString *identifier1 = @"labelCell";
- static NSString *identifier2 = @"imageCell";
- Person *person = self.allPersonsArray[indexPath.row];
- "]) {
- LableCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier1 forIndexPath:indexPath];
- cell.nameLabel.text = person.name;
- cell.statusLabel.text = person.status;
- return cell;
- }else {
- ImageViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier2 forIndexPath:indexPath];
- cell.nameLabel.text = person.name;
- cell.statusLabel.text = person.status;
- cell.myImageView.image = [UIImage imageNamed:person.imageName];
- return cell;
- }
- }
四、Cell自适应高度
- 当每个Cell都有不同的高度时,就需要Cell去自适应高度
- 方式为两种:
- 文本自适应高度:根据文本内容设定Label高度
- 图片自适应高度:根据图片宽度进行等比例缩放
- 这里需要创建一个新的类去封装这两个方法用以获得文本的高度和图片的高度:
- @interface CalculateTextHeight : NSObject
- // 声明类方法用来计算文本高度
- + (CGFloat)calculateTextHeightWithText:(NSString *)text
- font:(UIFont *)font;
- + (CGFloat)imageHeightWithImage:(UIImage *)image;
- @end
- 具体的实现
- @implementation CalculateTextHeight
- + (CGFloat)calculateTextHeightWithText:(NSString *)text font:(UIFont *)font
- {
- // iOS7.0中求文本高度的方法,返回一个CGRect的高度
- // 第一个参数,一个屏幕宽,10000高的文本
- CGSize size = CGSizeMake([UIScreen mainScreen].bounds.size.width, );
- // 第二个参数,设置以行高为单
- // 第三个参数,根据字体判断高度
- CGRect rect = [text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font} context:nil];
- return rect.size.height;
- }
- + (CGFloat)imageHeightWithImage:(UIImage *)image
- {
- // 得到图片的宽和高
- CGFloat width = image.size.width;
- CGFloat height = image.size.height;
- // 得到宽高比例和屏幕宽度
- float i = height / width;
- float j = [UIScreen mainScreen].bounds.size.width;
- CGFloat x = i * j;
- return x;
- }
- @end
iOS学习之UI自定义cell的更多相关文章
- iOS学习之UI可视化编程-XIB
一.Interface Builder可视化编程 1.Interface Builder简介: GUI:图形用户界面(Graphical User Interface,简称GUI,又称图形用户接口)是 ...
- iOS学习之UI可视化编程-StoryBoard
一.StoryBoard与xib 对比: 相同点:都属于IB编程的方式,可以快速构建GUI. 不同点:xib侧重于单文件(单独的控制器或者视图)编辑,storyboard侧重于多页面关联.storyb ...
- iOS学习之UITableView中Cell的操作
接着iOS学习之Table View的简单使用 这篇,这里主要讲UITableView 中的Cell的操作,包括标记.移动.删除.插入. 为了简单快捷,直接从原来那篇的代码开始,代码下载地址:http ...
- iOS 中使用 XIB 自定义cell 的两种方法 以及 编译出现常见 的错误 ++++(xcode6.0之后)
一. 注册cell 1.创建自定义cell并勾选 xib :(勾选xib就会自动生成与cell文件关联的xib) 2.在 tableViewController里注册自定义Cell (或者遵守tabl ...
- iOS 中使用 XIB 自定义cell的两种方法以及编译出现常见 的错误 (xcode6.0之后)
一. 注册cell 1.创建自定义cell并勾选 xib :(勾选xib就会自动生成与cell文件关联的xib) 2.在 tableViewController里注册自定义Cell (或者遵守tabl ...
- iOS开发总结-UITableView 自定义cell和动态计算cell的高度
UITableView cell自定义头文件:shopCell.h#import <UIKit/UIKit.h>@interface shopCell : UITableViewCell@ ...
- iOS 学习 - 18.TextField 自定义菜单事件,复制和微信分享
菜单事件包括,剪切.拷贝.全选.分享...,此 demo 只有 copy.share 1.定义 field 继承与 UITextField - (BOOL)canPerformAction:(SEL) ...
- iOS深入学习(UITableView系列4:使用xib自定义cell)
可以通过继承UITableViewCell重新自定义cell,可以像下面一样通过代码来自定义cell,但是手写代码总是很浪费时间, ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
- AJ学IOS(17)UI之纯代码自定义Cell实现新浪微博UI
AJ分享,必须精品 先看效果图 编程思路 代码创建Cell的步骤 1> 创建自定义Cell,继承自UITableViewCell 2> 根据需求,确定控件,并定义属性 3> 用get ...
随机推荐
- Android多线程异步处理:AsyncTask 的实现原理
AsyncTask主要用来更新UI线程,比较耗时的操作可以在AsyncTask中使用. AsyncTask是个抽象类,使用时需要继承这个类,然后调用execute()方法.注意继承时需要设定三个泛型P ...
- a mystrious max subquence sum
#include<cstdio>#include<cstring>const int maxn=100005;int buf[maxn];int main(){ freopen ...
- CSS 中 display:inline-block 属性使用详解
本文详细描述了display:inline-block的基础知识,产生的问题和解决方法以及其常见的应用场景,加深了对inline-block应用的进一步理解. 基础知识 display:inline- ...
- C# 加密算法
public static class Common { #region MD5加密 /// <summary> /// M ...
- IE6-IE9兼容性问题列表及解决办法总结
IE6-IE9兼容性问题列表及解决办法总结 概述 第一章:HTML. 3 第一节:IE7-IE8更新... 31.如果缺少结束标记的 P 元素后跟 TABLE.FORM.NOFRAMES 或 NOSC ...
- 码农谷 求前N项之和
题目描述 有一分数序列:2/1.3/2.5/3.8/5.13/8.21/13.......求出这个数列的前N项之和,保留两位小数. 输入描述 N 输出描述 数列前N项和 样例 输入: 输出: 16.4 ...
- Apache开启rewrite
1.找到LoadModule rewrite_module modules/mod_rewrite.so去掉前面的#号 2.找到AllowOverride None 改为:AllowOverride ...
- .NET常用类库知识总结
常用类库之.NET中的字符串 字符串的特性 1.不可变性 由于字符串是不可变的的,每次修改字符串,都是创建了一个单独字符串副本(拷贝了一个字符串副本).之所以发生改变只是因为指向了一块新 ...
- kbengine mmo源码(完整服务端源码+资源+完整客户端源码)
本项目作为kbengine服务端引擎的客户端演示而写 更新kbengine插件库(https://github.com/kbengine/kbengine_unity3d_plugins): ...
- Mysql的ssl主从复制+半同步主从复制
Mysql的ssl主从复制+半同步主从复制 准备工作 1.主从服务器时间同步 [root@localhost ~]# crontab -e */30 * * * * /usr/sbin/ntpdate ...