我想做的是创建一个文本容器组件,当有人触摸它时,它能够指示最近的单词是什么(即触摸点“后面”的单词)。
首先,我创建了一个 UILabel 子类并覆盖了 touchesEnded:withEvent: 方法来确定被触摸的 CGPoint。我还编写了一个方法,使用 sizeWithFont:forWidth:lineBreakMode: 计算文本中每个单词的相应“框架”(CGRect)。有了被触摸的 CGPoint 和这个框架,我可以确定实际被触摸的是哪个词。但是计算框架的方法只适用于单行文本。
所以现在我需要知道文本的哪一部分在给定的行上(即文本是如何拆分的),这样我才能计算出每个单词的正确左边距和上边距。
知道如何获得这个吗? 或者,也许您有更直接的解决方案来实现这一目标? This post was unfortunately not very helpful... ...
最佳答案
(在您的链接帖子中有一个指向示例代码项目的链接,其中确实包含一些有用的示例代码,但我也会在这里为您概述该过程。)
简而言之,您将需要使用 Core Text,它是 Apple 的基于 C 的高级文本处理框架,支持 iOS 和 OS X 中所有复杂的文本布局。
完整的代码会有些涉及,但您要查看的关键方法是:
CTFramesetterCreateWithAttributedString() - 将其与您将从标签文本中获得的 NSAttributedString 结合使用 - 创建框架 setter
CTFramesetterCreateFrame() - 使用它从上面的 framesetter 获取文本的 CTFrameRef。为此,您需要使用标签边界创建 CGPathRef。
CTFrameGetLines()、CTFrameGetLineOrigins() - 使用它们分别获取对应于排版行的 CTLineRefs 和行原点的坐标,然后使用 CTLineGetStringIndexForPosition() 查找触摸位置的字符索引。
然后您可以使用这个字符索引(在该行的引用框架中)向后工作并在您的完整字符串中找到实际的字符/单词/等。
不要忘记,有几个问题会使事情变得复杂:
如果您使用 UILabel 的原生绘图,您将必须注意完美匹配您的排版指标,这可能会很麻烦,因为大多数对象(例如 CTFontRef)都不是免费桥接它们的 UIKit 对象。有时,实现您自己的绘图可能会更容易,这将保证度量匹配。
Core Text 使用相对于普通 iOS 绘图系统的倒置坐标系。如果您得到了古怪的结果,尤其是如果您自己画画,这值得一看。
这不是世界上最简单的任务,但绝非不可能。祝你好运!
关于ios - 在 UILabel/UITextView 中获取文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8811909/
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解
有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur