<原>在一个tableView上应用不同类型的DTAttributedTextCell
2012-09-04 15:49
751 查看
[b]未经作者同意禁止转载[/b]
正在做一个项目,是一个考试答题系统,其题目的题干 或者选项都是用html语言描述的,有的题目题干甚至会出现一些复杂的公式
以及上下脚标,所以只能用 直接显示html的方法 因此找到了DTCoreText
但是由于DTCoreText 中的DTAttributedTextCell 形式特别不自由 其cell上显示html的时候 会填充到整个cell
而我们需要的效果是这样的
这样就需要我们自定义DTCoreText 中的DTAttributedTextCell 在cell上加上图片 或者别的东西 同时能调整cell上显示html所占的大小 自定义DTAttributedTextCell 方法 在随笔中有记载
但是在这个界面中 cell第一行 与其他4行并不相同, 第一行 只是原生的DTAttributedTextCell 只显示题干 而下面的四行 上面要有图片等一些东西 同时其显示html的view还不能填满整个cell
很明显 第一行和下面四行 不会是一个类型的cell 这也就引出了本文的目的
在一个tableView上加载不同类型的cell(不同的 class) 但都是根据DTAttributedTextCell 改编过来的 自定义的相关方法参照
另一篇随笔 本文主要讲怎么在tableView上引用,以及怎么修改DTCoreText中的一些代码 达到兼容 并且出现上面的效果
首先贴上我们自定义的两个cell
第一个cell 的class就是DTAttributedTextCell
第二个cell 的class是MyCell 其与DTAttributedTextCell基本相同,只不过DTAttributedTextCell 中是用代码创建的
DTAttributedTextContentView 加到了cell上 MyCell是 用storyboard创建的DTAttributedTextContentView
以及 别的控件 并进行连接 (与自定义相关的内容参照 自定义DTAttributedTextContentView)
[b]tableViewController.m 中[/b]
这里改动比较大 因为要引用两个不同的cell 所以要进行一些判断 来确定是读取,创建哪个 cell 尤其注意 不要刻意的定性某个cell
要先进行判断 再确定cell类型
上边两个方法是tableView 调用的第一层方法 里面都用if 进行了判断 然后 再确定相应的类型 并进行下一步调用
核心代码已经标出 同样要判断 要用哪个类型的cell 再创建对应的类型 注意 此方法 返回的参数为ID 因为我们不确定返回哪个类型的cell
这里同样进行判断来进行不同的初始化 加注释的代码有很重要的作用, 后面会详细解释
这时 cell引用没有问题 点击运行 如下图所示
第一个cell正常显示 MyCell 虽然在storyboard中我们并没有将 DTAttributedTextContentView设置为整个cell但是
运行后 仍然变为整个 cell
参考随笔(自定义DTAttributedTextCell) 我们知道 我们必须要修改一下DTAttributedTextContentView的relayoutText方法
[b][b]DTAttributedTextContentView.h[/b][/b]
我们自己定义了 两个实例
NSString *identifier;
CGSize realSize;
这就对应上了 我们在tableViewController.m中的
- (void)configureCell:(id)cell forIndexPath:(NSIndexPath *)indexPath
方法中的几句代码
在这里 我们判断出了到底使用哪个cell 然后 设定attributedTextContextView.identifier为某个特定的标记
并且将attributedTextContextView.frame.size的值传入attributedTextContextView.realSize
注意 对attributedTextContextView.identifier以及attributedTextContextView.frame.size的赋值一定要在
[myCell setHTMLString:html]; 方法之前 因为这个方法调用后 才会层层深入调用 一直调用到DTAttributedTextContentView.m 中的relayoutText方法 然后我们再读取identifier 以及realsize
若放到[myCell setHTMLString:html]; 之后赋值 进入relayoutText后 identifier realSize为空 根本无法判断
[b][b]DTAttributedTextContentView.m[/b][/b]
这段代码首先 我们根据我们事先设置好的identifier 确定了是哪个cell上的view 然后进行不同的尺寸设置
注意 这里不能直接把 if(isMyCell)换成 if([identifier isEqualtoString:@"xxx"])判断 这样会造成程序僵死 原因尚不明确
关于if()中对尺寸的设置 可以参考随笔 (自定义[b]DTAttributedTextContentView.m[/b])
[b]对本例的扩展:[/b]
如果我们tableView中存在更多的 cell类型 这里 可以根据这个思路, 再增加一组 identifier 并且 设置相应的尺寸
然后给isMyCell 增加编号 当然tableViewController中的判断 也要多加一个if判断 等等
正在做一个项目,是一个考试答题系统,其题目的题干 或者选项都是用html语言描述的,有的题目题干甚至会出现一些复杂的公式
以及上下脚标,所以只能用 直接显示html的方法 因此找到了DTCoreText
但是由于DTCoreText 中的DTAttributedTextCell 形式特别不自由 其cell上显示html的时候 会填充到整个cell
而我们需要的效果是这样的
这样就需要我们自定义DTCoreText 中的DTAttributedTextCell 在cell上加上图片 或者别的东西 同时能调整cell上显示html所占的大小 自定义DTAttributedTextCell 方法 在随笔中有记载
但是在这个界面中 cell第一行 与其他4行并不相同, 第一行 只是原生的DTAttributedTextCell 只显示题干 而下面的四行 上面要有图片等一些东西 同时其显示html的view还不能填满整个cell
很明显 第一行和下面四行 不会是一个类型的cell 这也就引出了本文的目的
在一个tableView上加载不同类型的cell(不同的 class) 但都是根据DTAttributedTextCell 改编过来的 自定义的相关方法参照
另一篇随笔 本文主要讲怎么在tableView上引用,以及怎么修改DTCoreText中的一些代码 达到兼容 并且出现上面的效果
首先贴上我们自定义的两个cell
第一个cell 的class就是DTAttributedTextCell
第二个cell 的class是MyCell 其与DTAttributedTextCell基本相同,只不过DTAttributedTextCell 中是用代码创建的
DTAttributedTextContentView 加到了cell上 MyCell是 用storyboard创建的DTAttributedTextContentView
以及 别的控件 并进行连接 (与自定义相关的内容参照 自定义DTAttributedTextContentView)
[b]tableViewController.m 中[/b]
这里改动比较大 因为要引用两个不同的cell 所以要进行一些判断 来确定是读取,创建哪个 cell 尤其注意 不要刻意的定性某个cell
要先进行判断 再确定cell类型
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { MyCell *myCell; DTAttributedTextCell *dtCell; if (indexPath.row==0) { dtCell=(DTAttributedTextCell *)[self tableView:tableView preparedCellForIndexPath:indexPath]; //return dtCell.attributedTextContextView.frame.size.height+10; return [dtCell requiredRowHeightInTableView:tableView]+20; }else{ myCell = (MyCell *)[self tableView:tableView preparedCellForIndexPath:indexPath]; return myCell.attributedTextContextView.frame.size.height+10; } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { id cell; if (indexPath.row==0) { cell=(DTAttributedTextCell *)[self tableView:tableView preparedCellForIndexPath:indexPath]; }else{ cell = (MyCell *)[self tableView:tableView preparedCellForIndexPath:indexPath]; } return cell; }
上边两个方法是tableView 调用的第一层方法 里面都用if 进行了判断 然后 再确定相应的类型 并进行下一步调用
- (id)tableView:(UITableView *)tableView preparedCellForIndexPath:(NSIndexPath *)indexPath { if (!cellCache) { cellCache = [[NSCache alloc] init]; } // workaround for iOS 5 bug NSString *key = [NSString stringWithFormat:@"%d-%d", indexPath.section, indexPath.row]; id cell = [cellCache objectForKey:key]; if (!cell) { // reuse does not work for variable height //cell = (DTAttributedTextCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) { //这里面是核心代码 判断是哪个类型 再创建对应的类型 if (indexPath.row==0) { cell = [[DTAttributedTextCell alloc] initWithReuseIdentifier:@"title" accessoryType:UITableViewCellAccessoryDisclosureIndicator]; }else{ cell=[myTableView dequeueReusableCellWithIdentifier:@"answer"]; } } // cache it [cellCache setObject:cell forKey:key]; } [self configureCell:cell forIndexPath:indexPath]; return cell; }
核心代码已经标出 同样要判断 要用哪个类型的cell 再创建对应的类型 注意 此方法 返回的参数为ID 因为我们不确定返回哪个类型的cell
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 5; } - (void)configureCell:(id)cell forIndexPath:(NSIndexPath *)indexPath { MyCell *myCell; DTAttributedTextCell *dtCell; if (indexPath.row==0) { dtCell=(DTAttributedTextCell *)cell; NSString *html=@"摘要: 其实说是DTAttributedTextCell解析并显示html 应该是cell上的DTAttributedTextContentView解析并显示html首先先说一下DTAttributedTextCell 解析显示html的优点a.能够很好的实现cell的自适应高度,用webView也能实现自适应高度,但是逻辑复杂,效率不高,有加"; //下面一句是代码的作用后面会解释 dtCell.attributedTextContextView.identifier=@"title"; [dtCell setHTMLString:html]; dtCell.userInteractionEnabled=NO; [dtCell setSelectionStyle:UITableViewCellSelectionStyleNone]; dtCell.attributedTextContextView.shouldDrawImages = YES; dtCell.attributedTextContextView.backgroundColor=[UIColor clearColor]; } else { myCell=(MyCell *)cell; NSString *html=@"V<sub>1</sub>+V<sub>2</sub>=V<sub>13</sub>"; //下面代码的作用后面会解释 myCell.attributedTextContextView.identifier=@"answer"; CGSize size=myCell.attributedTextContextView.frame.size; myCell.attributedTextContextView.realSize=size; [myCell setHTMLString:html]; myCell.ABCDlabel.text=@"A"; myCell.imageView.image=[UIImage imageNamed:@"answer-notselected"]; myCell.attributedTextContextView.backgroundColor=[UIColor clearColor]; myCell.attributedTextContextView.shouldDrawImages = YES; } }
这里同样进行判断来进行不同的初始化 加注释的代码有很重要的作用, 后面会详细解释
这时 cell引用没有问题 点击运行 如下图所示
第一个cell正常显示 MyCell 虽然在storyboard中我们并没有将 DTAttributedTextContentView设置为整个cell但是
运行后 仍然变为整个 cell
参考随笔(自定义DTAttributedTextCell) 我们知道 我们必须要修改一下DTAttributedTextContentView的relayoutText方法
[b][b]DTAttributedTextContentView.h[/b][/b]
@interface DTAttributedTextContentView : UIView { NSAttributedString *_attributedString; DTCoreTextLayoutFrame *_layoutFrame; UIEdgeInsets edgeInsets; NSMutableDictionary *customViewsForAttachmentsIndex; //这是我们自己给其添加的一个属性,用来区分不同的实例 NSString *identifier; //这个用来装载不同实例的 frame.size CGSize realSize; } @property(nonatomic,retain)NSString *identifier; @property(nonatomic)CGSize realSize;
我们自己定义了 两个实例
NSString *identifier;
CGSize realSize;
这就对应上了 我们在tableViewController.m中的
- (void)configureCell:(id)cell forIndexPath:(NSIndexPath *)indexPath
方法中的几句代码
myCell.attributedTextContextView.identifier=@"answer"; CGSize size=myCell.attributedTextContextView.frame.size; myCell.attributedTextContextView.realSize=size; [myCell setHTMLString:html];
在这里 我们判断出了到底使用哪个cell 然后 设定attributedTextContextView.identifier为某个特定的标记
并且将attributedTextContextView.frame.size的值传入attributedTextContextView.realSize
注意 对attributedTextContextView.identifier以及attributedTextContextView.frame.size的赋值一定要在
[myCell setHTMLString:html]; 方法之前 因为这个方法调用后 才会层层深入调用 一直调用到DTAttributedTextContentView.m 中的relayoutText方法 然后我们再读取identifier 以及realsize
若放到[myCell setHTMLString:html]; 之后赋值 进入relayoutText后 identifier realSize为空 根本无法判断
[b][b]DTAttributedTextContentView.m[/b][/b]
- (void)relayoutText { //CGRect frame=self.frame; //下面的代码进行判断 并利用isMyCell设定了一个标志 int isMyCell; if ([self.identifier isEqualToString:@"answer"]) { isMyCell=2; }else if(self.identifier==nil) { isMyCell=3; } else if([self.identifier isEqualToString:@"title"]) { isMyCell=1; } // Make sure we actually have a superview before attempting to relayout the text. if (self.superview) { // need new layouter self.layouter = nil; self.layoutFrame = nil; // remove all links because they might have merged or split [self removeAllCustomViewsForLinks]; if (_attributedString) { // triggers new layout CGSize neededSize; //这里根据isMyCell的值确定 是用的哪个cell再设定一些尺寸相关的代码 if (isMyCell==2) { neededSize = [self sizeThatFits:self.realSize]; self.frame = CGRectMake(152, self.frame.origin.y, neededSize.width, neededSize.height); } else if(isMyCell==1){ neededSize=[self sizeThatFits:self.bounds.size]; super.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, neededSize.width, neededSize.height); } // set frame to fit text preserving origin // call super to avoid endless loop [self willChangeValueForKey:@"frame"]; [self didChangeValueForKey:@"frame"]; } [self setNeedsDisplay]; [self setNeedsLayout]; } }
这段代码首先 我们根据我们事先设置好的identifier 确定了是哪个cell上的view 然后进行不同的尺寸设置
注意 这里不能直接把 if(isMyCell)换成 if([identifier isEqualtoString:@"xxx"])判断 这样会造成程序僵死 原因尚不明确
关于if()中对尺寸的设置 可以参考随笔 (自定义[b]DTAttributedTextContentView.m[/b])
[b]对本例的扩展:[/b]
如果我们tableView中存在更多的 cell类型 这里 可以根据这个思路, 再增加一组 identifier 并且 设置相应的尺寸
然后给isMyCell 增加编号 当然tableViewController中的判断 也要多加一个if判断 等等
相关文章推荐
- <原>DTCoreText学习(一)-DTAttributedTextCell原理
- <原>DTCoreText学习(三)-自定义DTAttributedTextCell
- tableView 使用注意事项:一个tableView展示不同的cell时复用,以及数据更新
- iOS 在一个TableView内使用不同的Cell
- 制作一个可以滑动操作的 Table View Cell
- 一个TextView设置不同大小字体、EditText显示两行不同样式hint
- 在一个tableView 中需要自定义多种样式的cell(两种或三种),通常你如何实现,说说思路即可?
- 同一个TextView如何显示不同颜色的文字、字体大小、字体样式
- 关于一个Textview内的文字设置不同大小和颜色
- 关于TableView中不止一个section的情况下首个cell的y轴不为0的会造成的问题和解决办法
- 深入理解TextView实现Rich Text--在同一个TextView设置不同字体风格
- 在tableView中监听cell上textField的点击和键盘通知
- iOS tableViewCell 在cell赋值、网络加载照片位置偏移大小错乱,做一个类似qq列表的tableview 更新3
- tableview的多个类型自定义cell的数据重用解决方案
- android 一个textview不同样式
- 在一个textview中显示两种不同颜色的字体
- 一个TextView内显示不同颜色的文字
- 在一个TextView中字体显示不同颜色
- Table View Cell中有TextField,实现界面随键盘上升
- UITableView“优雅”支持不同类型的Cell