IOS开发UI篇--UITableView的自定义布局==纯代码布局

UITableView中除了利用系统的UItableViewCell不能完成需求进行布局时,还可以进行自定义布局;

自定义布局分为两类:(1)利用代码进行创建

(2)利用xib进行实现;

下面对利用代码进行创建分析:


应用场景:像微博,等列表数据展示(由于微博的每个单元格的数据大小不一致,所以得计算每个单元格的大小)
分析:前提是获取列表数据,然后建立每个单元格的模型(建立单元格模型应继承UITableViewCell)复写
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
此方法即可,在此方法中添加单元格所需要的各个视图控件, 然后根据微博对象模型,确定每个控件的位置,并进行数据
的填充,
主要在此方法中几个重要的方法:(特别是方法的执行顺序)
1.-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
2.-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

下面以一个例子进行说明:

由于本案例整个界面就是单独的一个UITableView,故而主控制器设置成UITableViewController;这样可以减少很多连线问题,

因为UITableViewController里面已进行关联,且内部也开放出来了tableview;可以直接使用

(1)下面是一个SLViewController.m文件


  1 #import "SLViewController.h"
2
3 #import "SLWeiBo.h"
4 #import "SLWeiBoCell.h"
5 #import "SLWeiBoFrame.h"
6
7 @interface SLViewController ()
8
9 //定义数组,保存模型数据
10 @property (nonatomic,strong)NSArray *statusFrames;
11
12 @end
13
14 @implementation SLViewController
15
16 - (void)viewDidLoad
17 {
18 [super viewDidLoad];
19 self.tableView ;
20 }
21
22 #pragma mark -懒加载
23 -(NSArray *)statusFrames
24 {
25 if (_statusFrames==nil) {
26 //加载plist数据文件
27 NSString *fullpath=[[NSBundle mainBundle] pathForResource:@"statuses" ofType:@"plist"];
28 NSArray *arr=[NSArray arrayWithContentsOfFile:fullpath];
29 NSMutableArray *mutearr=[NSMutableArray arrayWithCapacity:arr.count];
30 for (NSDictionary *dict in arr) {
31 //字典转模型,传进去一个字典,返回一个微博模型
32 SLWeiBo *weibo=[SLWeiBo weiBoWithDict:dict];
33 //计算每一个表格的高度并保存
34 SLWeiBoFrame *weiboframe=[[SLWeiBoFrame alloc] init];
35 weiboframe.weibo=weibo;
36 //把Frame模型保存到数组中
37 [mutearr addObject:weiboframe];
38 }
39
40 self.statusFrames=[mutearr mutableCopy];
41 }
42 return _statusFrames;
43 }
44
45 #pragma mark -实现数据源方法
46 /**
47 * tableview中返回一共有多少组,有一组的话,可以省略不写
48 *
49 * @param tableView
50 *
51 * @return 返回有多少组
52 */
53 -(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
54 {
55 return 1;
56 }
57 /**
58 * tableview返回一共有多少个单元格
59 *
60 * @param tableView
61 * @param section 第几组
62 *
63 * @return 某组有多少单元格
64 */
65 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
66 {
67 return self.statusFrames.count;
68 }
69
70 /**
71 * tableView返回每个单元格的对象
72 *
73 * @param tableView
74 * @param indexPath 保存有该对象是第几组,第几个单元格
75 *
76 * @return 返回每个单元格对象
77 */
78 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
79 {
80 //1.从缓存中取数据
81 static NSString *identifier=@"status";
82 SLWeiBoCell *cell=[tableView dequeueReusableCellWithIdentifier:identifier];
83 //2创建表格
84 if (cell==nil) {
85 cell=[[SLWeiBoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
86 }
87 //3设置数据
88 SLWeiBoFrame *frame=self.statusFrames[indexPath.row];
89 cell.itemframe=frame;
90 return cell;
91 }
92 #pragma mark -实现高度的代理方法
93 /**
94 * 计算每个单元格的高度
95 *
96 * @param tableView
97 * @param indexPath 该单元格是某组某行的单元格
98 *
99 * @return 返回该单元格的高度
100 */
101 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
102 {
103 SLWeiBoFrame *frame=self.statusFrames[indexPath.row];
104 return frame.cellHeight;
105 }
106 /**
107 * 设置是否显示状态栏
108 *
109 * @return 返回YES,不显示,返回NO,显示
110 */
111 -(BOOL)prefersStatusBarHidden
112 {
113 return NO;
114 }
115 @end

(2)这个SLWeiBo.H与SLWeiBo.m Global.h文件

第一个文件是定义一些基本属性,用来进行字典转换模型;并定义了两个方法,一个是类方法,一个实例方法,在第二个文件中进行实现

第三个文件是对第一个和第二个文件的定义方法进行的抽取,方便重用,第三个文件利用定义宏进行代码抽取,


 1 #import "Global.h"
2 /**
3 * 创建一个微博对象,保存模型数据
4 */
5 @interface SLWeiBo : NSObject
6
7 @property (nonatomic,copy) NSString *text;//内容
8 @property (nonatomic,copy) NSString *icon;//头像
9 @property (nonatomic,copy) NSString *name;//昵称
10 @property (nonatomic,copy) NSString *picture;//配图
11 //是否是vip
12 @property (nonatomic,assign) BOOL vip;
13
14 initWeiBo(weiBo)
15 ////进行转换的实例方法
16 //-(instancetype)initWithWeiBo:(NSDictionary *)dict;
17 //// 进行转换的类方法
18 //+(instancetype)weiBoWithDict:(NSDictionary *)dict;
19
20 @end


 1 #import "SLWeiBo.h"
2
3 @implementation SLWeiBo
4
5 //分别对类方法和实例方法进行实现
6 weiBoInitDict(weiBo);
7 //-(instancetype)initWithWeiBo:(NSDictionary *)dict;
8 //{
9 // if (self=[super init]) {
10 // [self setValuesForKeysWithDictionary:dict];
11 // }
12 // return self;
13 //}
14 //
15 //+(instancetype)weiBoWithDict:(NSDictionary *)dict
16 //{
17 // return [[self alloc] initWithWeiBo:dict];
18 //}
19
20 @end


 1 #ifndef ___Global_h
2 #define ___Global_h
3
4 #define initWeiBo(name) 5 -(instancetype) initWithWeiBo:(NSDictionary *)dict; 6 +(instancetype) name##WithDict:(NSDictionary *)dict;
7
8 #define weiBoInitDict(name) 9 -(instancetype) initWithWeiBo:(NSDictionary *)dict;10 {11 if (self=[super init]) {12 [self setValuesForKeysWithDictionary:dict];13 }14 return self;15 }16 +(instancetype) name##WithDict:(NSDictionary *)dict17 {18 return [[self alloc] initWithWeiBo:dict];19 }
20 #endif

(3)SLWeiBoCell.h和SLWeiBoCell.m文件是继承自UITableViewCell的,是对UITableViewCell进行的重写,已到达所需要的要求界面,

  并设置数据,与设置位置。


1 #import <UIKit/UIKit.h>
2 @class SLWeiBoFrame;
3
4 @interface SLWeiBoCell : UITableViewCell
5 //导入SLweiboFrame对象,保存着一个单元格里面每个控件的位置,及weibo对象
6 @property (nonatomic,strong) SLWeiBoFrame *itemframe;
7
8 @end


  1 #import "SLWeiBoCell.h"
2
3 #import "SLWeiBoFrame.h"
4
5 #define SLFontNiCheng [UIFont systemFontOfSize:15]
6 #define SLFontZhengWen [UIFont systemFontOfSize:16]
7 @interface SLWeiBoCell()
8 //头部头像
9 @property (nonatomic,weak) UIImageView *iconheader;
10 //昵称
11 @property (nonatomic,weak) UILabel *nicheng;
12 //是否是vip
13 @property (nonatomic,weak) UIImageView *vip;
14 //正文显示
15 @property (nonatomic,weak) UILabel *zhengwen;
16 //配图显示
17 @property (nonatomic,weak) UIImageView *peitu;
18
19 @end
20
21 @implementation SLWeiBoCell
22
23 //复写此方法,以达到重写UITableViewCell的目的
24 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
25 {
26 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
27 if (self) {
28 // 让自定义cell和系统的cell一样,创建出来就拥有一些子控件提供给我们使用
29 //1.创建头像
30 UIImageView *iconheader=[[UIImageView alloc] init];
31 [self.contentView addSubview:iconheader];
32 self.iconheader=iconheader;
33 //2.创建昵称
34 UILabel *nicheng=[[UILabel alloc] init];
35 nicheng.font=SLFontNiCheng;
36 [self.contentView addSubview:nicheng];
37 self.nicheng=nicheng;
38 //3.创建vip
39 UIImageView *vip=[[UIImageView alloc] init];
40 vip.image=[UIImage imageNamed:@"vip"];
41 [self.contentView addSubview:vip];
42 self.vip=vip;
43 //4创建正文
44 UILabel *zhengwen=[[UILabel alloc] init];
45 //让正文进行多行显示
46 zhengwen.numberOfLines=0;
47 //设置正文的字体,此时的字体应该在和计算该正文的字体长宽所用字体一致,
48 zhengwen.font=SLFontZhengWen;
49 [self.contentView addSubview:zhengwen];
50
51 self.zhengwen=zhengwen;
52 //5创建配图
53 UIImageView *peitu=[[UIImageView alloc] init];
54 [self.contentView addSubview:peitu];
55 self.peitu=peitu;
56 }
57 return self;
58 }
59 -(void)setItemframe:(SLWeiBoFrame *)itemframe
60 {
61 _itemframe=itemframe;
62 //设置数据
63 [self settingData];
64 //设置frame
65 [self settingFrame];
66 }
67
68 -(void)settingData
69 {
70 //设置头像
71 SLWeiBo *weibof=self.itemframe.weibo;
72 self.iconheader.image=[UIImage imageNamed:weibof.icon];
73 //设置昵称
74 self.nicheng.text=weibof.name;
75 //设置vip
76 if (weibof.vip) {
77 self.nicheng.textColor=[UIColor redColor];
78 self.vip.hidden=NO;
79 }else{
80 self.nicheng.textColor=[UIColor blackColor];
81 self.vip.hidden=YES;
82 }
83 //设置内容
84 self.zhengwen.text=weibof.text;
85 //设置配图
86 if (weibof.picture) {
87 self.peitu.image=[UIImage imageNamed:weibof.picture];
88 self.peitu.hidden=NO;
89 }else{
90 self.peitu.hidden=YES;
91 }
92 }
93
94 -(void)settingFrame
95 {
96 //1设置头像的frame
97 self.iconheader.frame=self.itemframe.iconF;
98 //2设置昵称的frame
99 self.nicheng.frame=self.itemframe.nichengF;
100 //3设置vip的frame
101 self.vip.frame=self.itemframe.vipF;
102 //4设置正文的frame
103 self.zhengwen.frame=self.itemframe.zhengwenF;
104 //5设置配图的frame
105 if (self.itemframe.weibo.picture) {
106 self.peitu.frame=self.itemframe.peituF;
107 }
108 }
109 @end

(4)SLWeiBoFrame.h和SLWeiBoFrame.m
文件是为了求行高而进行的数据抽取,即先计算出行的高,并且保存每行中控件的位置;

方便传给cell进行利用;


 1 #import "SLWeiBo.h"
2 @interface SLWeiBoFrame : NSObject
3
4 /**
5 头像的frame
6 */
7 @property (nonatomic,assign) CGRect iconF;
8 /**
9 昵称的frame
10 */
11 @property (nonatomic,assign) CGRect nichengF;
12 /**
13 vip的frame
14 */
15 @property (nonatomic,assign) CGRect vipF;
16 /**
17 正文的frame
18 */
19 @property (nonatomic,assign) CGRect zhengwenF;
20 /**
21 配图的frame
22 */
23 @property (nonatomic,assign) CGRect peituF;
24 /**
25 行高
26 */
27 @property (nonatomic,assign) CGFloat cellHeight;
28 @property (nonatomic,strong) SLWeiBo *weibo;
29
30 @end


 1 #import "SLWeiBoFrame.h"
2 #import "SLWeiBo.h"
3 #define SLFontNiCheng [UIFont systemFontOfSize:15]
4 #define SLFontZhengWen [UIFont systemFontOfSize:16]
5 @implementation SLWeiBoFrame
6
7
8 -(void)setWeibo:(SLWeiBo *)weibo
9 {
10
11 _weibo=weibo;
12 //间隙
13 CGFloat padding=10;
14 //1设置头像的frame
15 CGFloat iconViewX=padding;
16 CGFloat iconViewY=padding;
17 CGFloat iconViewW=30;
18 CGFloat iconViewH=30;
19 self.iconF=CGRectMake(iconViewX, iconViewY, iconViewW, iconViewH);
20
21 //2设置昵称的frame
22 CGFloat nichengX=CGRectGetMaxX(self.iconF)+padding;
23 /**
24 * attributes 告诉系统文字的大小
25 */
26 // NSDictionary *[email protected]{NSFontAttributeName:[UIFont systemFontOfSize:15]};
27
28 // 如果将来计算的文字的范围超出了指定的范围,就返回的就是指定的范围
29 //如果将来的文字范围小于指定的范围,就返回实际的范围
30 CGSize maxsize=CGSizeMake(MAXFLOAT, MAXFLOAT);
31 CGSize namesize=[self sizeWithString:_weibo.name font:SLFontNiCheng maxSize:maxsize];
32 // CGRect namesize= [_weibo.name boundingRectWithSize:maxsize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];
33
34 CGFloat nichengH=namesize.height;
35 CGFloat nichengW=namesize.width;
36
37 CGFloat nichengY=(self.iconF.size.height-nichengH)*0.5+iconViewY;
38 self.nichengF=CGRectMake(nichengX , nichengY, nichengW,nichengH);
39
40
41 //3设置vip的frame
42 CGFloat vipViewX=CGRectGetMaxX(self.nichengF)+padding;
43 CGFloat vipViewY=nichengY;
44 CGFloat vipViewW=14;
45 CGFloat vipViewH=14;
46 self.vipF=CGRectMake(vipViewX, vipViewY, vipViewW, vipViewH);
47
48
49 //4设置正文的frame
50
51 CGFloat zhengwenX=iconViewX;
52 CGFloat zhengwenY=CGRectGetMaxY(self.iconF)+padding;
53
54 CGSize maxsize1=CGSizeMake(300, MAXFLOAT);
55 CGSize zhengwensize=[self sizeWithString:_weibo.text font:SLFontZhengWen maxSize:maxsize1];
56 CGFloat zhengwenW=zhengwensize.width;
57 CGFloat zhengwenH=zhengwensize.height;
58
59 self.zhengwenF=CGRectMake(zhengwenX, zhengwenY, zhengwenW, zhengwenH);
60 //5设置配图的frame
61 // CGFloat cellHeight=0;
62 if (_weibo.picture) {
63 CGFloat peituX=iconViewX;
64 CGFloat peituY=CGRectGetMaxY(self.zhengwenF)+padding;
65 CGFloat peituW=100;
66 CGFloat peituH=100;
67 self.peituF=CGRectMake(peituX, peituY, peituW, peituH);
68 self.cellHeight=CGRectGetMaxY(self.peituF)+padding;
69 }else
70 {
71 //无配图的情况下的行高
72 self.cellHeight=CGRectGetMaxY(self.zhengwenF)+padding;
73 }
74 }
75
76 /**
77 * 计算文本的宽高
78 *
79 * @param str 文本显示
80 * @param font 文本显示的字体
81 * @param maxSize 文本显示的此存
82 *
83 * @return
84 */
85 -(CGSize)sizeWithString:(NSString *)str font:(UIFont *)font maxSize:(CGSize)maxSize
86 {
87 NSDictionary *dict=@{NSFontAttributeName: font};
88 CGSize nasize=[str boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil].size;
89 return nasize;
90 }
91
92 @end

最终实现效果图如下:

以上方法,即是利用代码进行对UITableViewCell进行的重写,下一讲讲解关于

利用xib创建重用的单元格对象。

IOS开发UI篇--UITableView的自定义布局==纯代码布局,布布扣,bubuko.com

时间: 2024-08-02 06:57:41

IOS开发UI篇--UITableView的自定义布局==纯代码布局的相关文章

IOS开发UI篇--UITableView的自定义布局==xib布局

利用Xib进行实现 应用场景:像团购网站的列表数据显示,新闻列表显示等(由于该类的显示的数据单元格内容格式相同) (1)主控制器文件,在文件中实现了自己自定义的代理,加载数据, 1 #import "SLViewController.h" 2 #import "SLTgDatas.h" 3 #import "SLTableViewCell.h" 4 #import "SLFooterView.h" 5 #import &quo

iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局

iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局 一.项目文件结构和plist文件 二.实现效果 三.代码示例 1.没有使用配套的类,而是直接使用xib文件控件tag值操作 数据模型部分: YYtg.h文件 // // YYtg.h // 01-团购数据显示(没有配套的类) // // Created by apple on 14-5-29. // Copyright (c) 2014年 itcase. All rights reserved. //

iOS开发UI篇—UITableview控件基本使

iOS开发UI篇—UITableview控件基本使用 一.一个简单的英雄展示程序 NJHero.h文件代码(字典转模型) #import <Foundation/Foundation.h> @interface NJHero : NSObject /** * 头像 */ @property (nonatomic, copy) NSString *icon; /** * 名称 */ @property (nonatomic, copy) NSString *name; /** * 描述 */ @

iOS开发UI篇—UITableview控件使用小结

iOS开发UI篇—UITableview控件使用小结 一.UITableview的使用步骤 UITableview的使用就只有简单的三个步骤: 1.告诉一共有多少组数据 方法:- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; 2.告诉每组一共有多少行 方法:- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSIntege

学习IOS开发UI篇--UITableView/数据模型嵌套/UITableViewCell/Cell的重用

1.UITableView ================================================== UITableView有两种格式:group和plain 2.UITableView如何展示数据 ================================================== UITableView需要一个数据源(dataSource)来显示数据 凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的

iOS开发UI篇—CAlayer(自定义layer)

iOS开发UI篇—CAlayer(自定义layer) 一.第一种方式 1.简单说明 以前想要在view中画东西,需要自定义view,创建一个类与之关联,让这个类继承自UIView,然后重写它的DrawRect:方法,然后在该方法中画图. 绘制图形的步骤: (1)获取上下文 (2)绘制图形 (3)渲染图形 如果在layer上画东西,与上面的过程类似. 代码示例: 新建一个类,让该类继承自CALayer YYMylayer.m文件 1 // 2 // YYMylayer.m 3 // 05-自定义l

iOS开发UI篇—UITableView全面解析

概述 在iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,类似于微信.QQ.新浪微博等软件基本上随处都是UITableView.当然它的广泛使用自然离不开它强大的功能,今天这篇文章将针对UITableView重点展开讨论.今天的主要内容包括: 基本介绍 数据源 代理 性能优化 UITableViewCell 常用操作 UITableViewController MVC模式 基本介绍 UITableView有两种风格:UITableViewSt

iOS开发UI篇—UITableView的常用属性与方法

UITableView UITableView内置了两种样式:UITableViewStylePlain,UITableViewStyleGrouped <UITableViewDataSource,UITableViewDelegate>里的方法: tableView处理步骤 #pragma mark 1.有多少组 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView #pragma mark 2.第section

iOS开发UI篇—UITableview控件基本使用

一.一个简单的英雄展示程序 NJHero.h文件代码(字典转模型) 1 #import <Foundation/Foundation.h> 2 3 @interface NJHero : NSObject 4 /** 5 * 头像 6 */ 7 @property (nonatomic, copy) NSString *icon; 8 /** 9 * 名称 10 */ 11 @property (nonatomic, copy) NSString *name; 12 /** 13 * 描述 1