我的问题是:我在一个iOS应用程序中有动态内容(例如推特 - 尽管这不是一个推特应用程序),包括文本和图像(主要是图标/表情符号和缩略图)。我想在一个表格行中同时呈现文本和图像。主要困难在于每一行都会有不同的大小(使缓存更加困难),而且我需要动态计算图像大小,以适应每个图像出现时周围的文本(我可以有像20个表情符号挨着另一个+文本+更多表情符号等)。
我已经寻找了一些方法并尝试了几种方法。我的最初想法是使用UIWebView。我能够创建一个每行一个UIWebView的示例应用程序,即使对于预渲染单元格的一些“智能”NSCache,性能也不是很好,而且我必须处理UIWebView javascript回调来确定何时正确加载内容。
我的第二次尝试是为新的UITableViewCell覆盖drawRect。在drawRect方法中,我使用NSAttributedString和NSSelectorFromString来设置每种内容的范围(常规文本、粗体、斜体、不同颜色、图像)。为了适应图像,我使用CTRunDelegateCallbacks回调(getAscent、getDescent、getWidth)。就像这样:
我已经寻找了一些方法并尝试了几种方法。我的最初想法是使用UIWebView。我能够创建一个每行一个UIWebView的示例应用程序,即使对于预渲染单元格的一些“智能”NSCache,性能也不是很好,而且我必须处理UIWebView javascript回调来确定何时正确加载内容。
我的第二次尝试是为新的UITableViewCell覆盖drawRect。在drawRect方法中,我使用NSAttributedString和NSSelectorFromString来设置每种内容的范围(常规文本、粗体、斜体、不同颜色、图像)。为了适应图像,我使用CTRunDelegateCallbacks回调(getAscent、getDescent、getWidth)。就像这样:
CTRunDelegateCallbacks callbacks;
callbacks.version = kCTRunDelegateVersion1;
callbacks.getAscent = ascentCallback;
callbacks.getDescent = descentCallback;
callbacks.getWidth = widthCallback;
CTRunDelegateRef delegate = CTRunDelegateCreate(&callbacks, (__bridge void *)imgAttr); // img Attr is a Dictionary with all image info
有关此方法的更多详细信息,请查看这篇优秀的文章:http://www.raywenderlich.com/4147/how-to-create-a-simple-magazine-app-with-core-text#
最后,有两个问题:
这是最好的方法吗?我能否在性能良好的情况下完成此操作?我想知道每次滚动时是否需要为每个单元格调用drawRect会不方便 - 是否有任何事情我可以提前做?我已经玩了一段时间,它仍然很卡顿 - 但我还没有尝试在单独的线程中缓存每一行并在cellForRowAtIndexPath中使用它(尽管这可能超过内存使用);
我无法找到获取每个tableview单元格的行高的最佳方法。在NSAttributedString正确处理所有内容后,我如何知道我的drawRect函数使用的高度?
--- 添加更多信息
在我的drawRect创建所有内容(字符串和图像)之后,我正在尝试使用boundingRectWithSize获取正确的高度:
CGRect frame = [self.attString boundingRectWithSize:CGSizeMake(320, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading | NSStringDrawingUsesDeviceMetrics context:nil];
如果只有文本,这个功能可以很好地工作,但是当我将图像字符添加到内容中时,它无法正确计算高度...