草庐IT

带有一起呈现的动态文本和图像的 iOS UITableView(NSAttributedString + 图像)

coder 2023-09-27 原文

我的问题是:我在 iOS 应用程序(例如 twits - 虽然这不是 twitter 应用程序)中包含文本和图像(主要是图标/表情符号和缩略图)的动态内容。我想在表格行中同时呈现文本和图像。这里的主要困难是每一行都有不同的大小(使缓存更难),我需要动态计算图像大小以适合每个图像出现的文本(我可以有 20 个表情符号一个挨着一个 + 文本 + 更多表情符号 + 等)。

我一直在四处寻找并尝试了一些方法。我最初的想法是使用 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];

如果它只是文本,这工作正常,但是当我将图像字形添加到内容时,它无法正确计算高度...

最佳答案

我遇到了同样的问题,今天解决了。我正在使用 CTRunDelegateCallbacks 在文本之间绘制自定义对象,但是 boundingRectWithSize:options:context: 没有给我正确的高度。 (它忽略了我的自定义对象)。

相反,我在 Core Text 中找到了一个较低级别的 API,它满足所有要求并且完全正确。我为那个问题创建了一个类别。玩得开心! :-)

头文件:

#import <Foundation/Foundation.h>

@interface NSAttributedString (boundsForWidth)

- (CGRect)boundsForWidth:(float)width;

@end

执行文件:

#import "NSAttributedString+boundsForWidth.h"
#import <CoreText/CoreText.h>

@implementation NSAttributedString (boundsForWidth)

- (CGRect)boundsForWidth:(float)width
{
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self);

    CGSize maxSize = CGSizeMake(width, 0);

    CGSize size = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, maxSize, nil);

    CFRelease(framesetter);

    return CGRectMake(0, 0, ceilf(size.width), ceilf(size.height));
}

@end

关于带有一起呈现的动态文本和图像的 iOS UITableView(NSAttributedString + 图像),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16586190/

有关带有一起呈现的动态文本和图像的 iOS UITableView(NSAttributedString + 图像)的更多相关文章

  1. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  2. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  5. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. ruby-on-rails - 在 Ruby (on Rails) 中使用 imgur API 获取图像 - 2

    我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path

  8. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  9. ruby-on-rails - 带有 Zeus 的 RSpec 3.1,我应该在 spec_helper 中要求 'rspec/rails' 吗? - 2

    使用rspec-rails3.0+,测试设置分为spec_helper和rails_helper我注意到生成的spec_helper不需要'rspec/rails'。这会导致zeus崩溃:spec_helper.rb:5:in`':undefinedmethod`configure'forRSpec:Module(NoMethodError)对thisissue最常见的回应是需要'rspec/rails'。但这是否会破坏仅使用spec_helper拆分rails规范和PORO规范的全部目的?或者这无关紧要,因为Zeus无论如何都会预加载Rails?我应该在我的spec_helper中做

  10. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

随机推荐