4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
热卖商品
新闻详情
IOS-自定义cell与控件布局 - 阿莫西林 - CSDN博客
来自 : CSDN技术社区 发布时间:2021-03-25

\"\"


需要解决的问题:

1. 根据文字判断CGsize.

2. 根据最后一个控件的高度判断cell的高度.

3. 对整体模块化实现.

关于尺寸问题,补充下.  控件的位置描述是一个frame控制的,它包含两个结构体, 一个origin控制水平位置和垂直位置; 一个size控制宽度,和高度;

当我们计算文字的CGsize时候, 就是计算文字的宽度, 高度.

他们都是结构体,但是我们一般 不直接使用结构的语法进行赋值, 而是使用已有的方法, 比如对frame赋值使用CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height);

对CGsize赋值使用CGSizeMake(w, h);

计算文字的CGsize方法

 - (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context


当我们做一个tableView的时候, 只需要按照步骤走即可.

1. tableView的组数,默认是1.

2.tableView分组中的行数(cell).

3.每一个cell的具体显示, 包括内容和位置两部分

4.一些附加的控制属性, 行高, 响应事件等等....

我们只要按照这个思路去完成就可以了...



关于数据模型方面, 以前我们使用的是xib直接布局的,不存在太多的布局.这次我们没有使用xib, 每一个cell都需要我们布局, 我们可以把cell所需要的信息放到一个类中.

这个类包括cell的内容信息和frame信息.

其他关于数据转模型的就不细说了 ,但是要说一点,这次模拟放到内存中的数组就不仅仅是数据了,还需要frame,所以应该是一个描述cell类的类型数组.


类封装:

cell内容类

 interface AMMicroBlog : NSObject property (nonatomic, copy) NSString * text; property (nonatomic, copy) NSString * icon; property (nonatomic, copy) NSString * name; property (nonatomic, copy) NSString * picture; property (nonatomic, assign, getter isVip) BOOL vip;- (instancetype) initWithDic : (NSDictionary *) dic; (instancetype) microBlogWithDic : (NSDictionary *) dic; (NSArray *) microBlogsList; end

cell的frame类(包含一个AMMicroBlog对象)

这个类就可以完整的描述cell所需要的所有信息.

#import Foundation/Foundation.h #import UIKit/UIKit.h class AMMicroBlog; interface AMMicroBlogFrame : NSObject property (nonatomic, strong) AMMicroBlog * microBlog; /* 核心语句 */ property (nonatomic, assign, readonly) CGRect iconFrame; span style white-space:pre /span /* 通过microBlog的setter方法,完成对所有属性的据算, 赋值* / property (nonatomic, assign, readonly) CGRect nameFrame; property (nonatomic, assign, readonly) CGRect vipFrame; property (nonatomic, assign, readonly) CGRect textFrame; property (nonatomic, assign, readonly) CGRect pictureFrame; property (nonatomic, assign, readonly) CGFloat rowHeight; end


自定义cell类

该类通过一个AMMicroBlogFrame对象将以上两个类封装起来.

#import UIKit/UIKit.h class AMMicroBlogFrame; interface AMMicroBlogCell : UITableViewCell property (nonatomic, strong) AMMicroBlogFrame * microBlogFrame; /* 核心语句 */ (instancetype) microBlogCellWithTableView : (UITableView *) tableView; end

对于frame的计算时机,最早可以在从外部取的数据的时候就可以计算出frame, 因为只有文字的尺度是动态计算的.

在给内存中的模拟数组取值的时候就计算....

 property (nonatomic, strong) NSArray * microBlogFrames;


- (NSArray *)microBlogFrames{ if (!_microBlogFrames) { NSArray * microBlogs [AMMicroBlog microBlogsList]; NSMutableArray * frames [NSMutableArray array]; for (AMMicroBlog * blog in microBlogs) { AMMicroBlogFrame * frame [[AMMicroBlogFrame alloc] init]; frame.microBlog blog; //micrBlog的setter方法中,根据内容计算出frame [frames addObject: frame]; } _microBlogFrames frames; } return _microBlogFrames;}


 AMMicroBlogFrame * frame [[AMMicroBlogFrame alloc] init]; frame.microBlog blog; //micrBlog的setter方法中,根据内容计算出frame

AMMicroBlogFrame类中有一个AMMicroBlog类的microBlog属性,我们重写则个属性额setter方法, 在该方法中计算出AMMicroBlogFrame类中frame属性值.

 implementation AMMicroBlogFrame

- (void)setMicroBlog:(AMMicroBlog *)microBlog{ _microBlog microBlog; CGFloat margin 10; //头像 CGFloat iconW 30; CGFloat iconH 30; CGFloat iconX margin; CGFloat iconY margin; _iconFrame CGRectMake(iconX, iconY, iconW, iconH); //名字 CGSize nameSize [self sizeWithText: self.microBlog.name maxSize: CGSizeMake(MAXFLOAT, MAXFLOAT) fontSize: 15]; CGFloat nameX CGRectGetMaxX(_iconFrame) margin; CGFloat nameY iconY (iconH - nameSize.height) / 2; _nameFrame CGRectMake(nameX, nameY, nameSize.width, nameSize.height); //VIP CGFloat vipW 14; CGFloat vipH 14; CGFloat vipY nameY; CGFloat vipX CGRectGetMaxX(_nameFrame) margin; _vipFrame CGRectMake(vipX, vipY, vipW, vipH); //内容 CGSize textSize [self sizeWithText: self.microBlog.text maxSize: CGSizeMake(355, MAXFLOAT) fontSize: 14]; CGFloat textX iconX; CGFloat textY CGRectGetMaxY(_iconFrame) margin; _textFrame CGRectMake(textX, textY, textSize.width, textSize.height); //图片 if (self.microBlog.picture) { CGFloat pictureW 100; CGFloat pictureH 100; CGFloat pictureX margin; CGFloat pictureY margin CGRectGetMaxY(_textFrame); _pictureFrame CGRectMake(pictureX, pictureY, pictureW, pictureH); _rowHeight CGRectGetMaxY(_pictureFrame) margin; }else{ _rowHeight CGRectGetMaxY(_textFrame) margin; }}- (CGSize) sizeWithText : (NSString *) text maxSize : (CGSize) maxSize fontSize: (CGFloat) fontSize{ // CGSize maxSize CGSizeMake(MAXFLOAT, MAXFLOAT); CGSize nameSize [text boundingRectWithSize:maxSize options: NSStringDrawingUsesLineFragmentOrigin attributes: {NSFontAttributeName : [UIFont systemFontOfSize: fontSize]} context: nil].size; return nameSize;}


到此cell所需要的数据都已经完整了......

下面就是按照tableView生成的一般过程就OK了.

分组---行数---cell内容


在tableView的创建过程中,对于行高的控制,如果行高都是一样的可以直接用rowHeight属性, 但是往往行高不一致,那就需要使用代理方法控制

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ AMMicroBlogFrame * frame self.microBlogFrames[indexPath.row]; return frame.rowHeight; }

通过我们调试 发现, 这个代理方法的执行是在  cell内容之前的, 也就是执行

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

然后在执行

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

这一点很重要, 如果我们没有在最开始的时候就求的了 cell的所有frame数据, 那么让我们执行行高方法的时候, 很可能无法拿到行高的数值.



分组----行数

我们就此省略, 直接写cell内容方法..

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { AMMicroBlogCell * cell [AMMicroBlogCell microBlogCellWithTableView: tableView]; AMMicroBlogFrame * microBlog self.microBlogFrames[indexPath.row]; cell.microBlogFrame microBlog; /*****核心语句******/ return cell;}


当执行到

 cell.microBlogFrame microBlog; /*****核心语句******/
这条语句的时候,  AMMicroBlogFrame类中的microBlogFrame属性的setter方法会完成一系列的 cell赋值-------内容和frame.


microBlogFrame的setter方法:


- (void)setMicroBlogFrame:(AMMicroBlogFrame *)microBlogFrame{ _microBlogFrame microBlogFrame; span style white-space:pre /span //只需也要拿到一个 AMMicroBLogFrame对象就可以完成内容和frame的设置, 参详AMMicroBlogFrame类定义 [self setSubViewsContent]; //内容 [self setSubViewsFrame]; span style white-space:pre /span //frame}- (void) setSubViewsContent{ AMMicroBlog * microBlog self.microBlogFrame.microBlog; self.iconView.image [UIImage imageNamed: microBlog.icon]; self.nameView.text microBlog.name; self.vipView.image [UIImage imageNamed: vip if(! microBlog.isVip){ self.vipView.hidden YES; self.nameView.textColor [UIColor blackColor]; //因为cell的复用所以考虑对控件的属性设置,不然复用时候会出现问题 }else{ self.vipView.hidden NO; self.nameView.textColor [UIColor redColor]; } self.textView.text microBlog.text; if(microBlog.picture){ self.pictureView.image [UIImage imageNamed: microBlog.picture]; }}- (void) setSubViewsFrame{ self.iconView.frame self.microBlogFrame.iconFrame; self.nameView.frame self.microBlogFrame.nameFrame; self.vipView.frame self.microBlogFrame.vipFrame; self.textView.frame self.microBlogFrame.textFrame; self.pictureView.frame self.microBlogFrame.pictureFrame;}


Done


代码很简答, 但是其中的 处理问题的思想 很重要....再钓到鱼的同时 还 要学到如何做一个 渔者!


封装总结, 首先创建源数据类模型, AMMicroBLog,  然后在AMMicoBlogFrame中封装AMMicroBlog, 最后在AMMicroBlogCell中封装AMMicoBlogFrame...


AMMicroBlog----------- AMMicroBlogFrame------------ AMMicroBlogCell


还有一个重要的对setter和geterr方法的使用..............OC中这个语法, 确实不错!





\"\" \"\" \"\" 点赞 1 \"\" \"\" 评论

本文链接: http://blogcell.immuno-online.com/view-768153.html

发布于 : 2021-03-25 阅读(0)
公司介绍
品牌分类
联络我们
服务热线:4000-520-616
(限工作日9:00-18:00)
QQ :1570468124
手机:18915418616
官网:http://