如何在 Swift 中为 iOS 制作垂直文本 UILabel 和 UITextView?

2024-02-19

如果您根据标题提出这个问题,但对蒙古语不感兴趣,您可能会寻找以下问答:

  • Swift:如何旋转 UIButton 和 UILabel 的文本? https://stackoverflow.com/questions/28717634/swift-how-can-you-rotate-text-for-uibutton-and-uilabel

我一直在学习 Swift,以便开发 iOS 应用程序传统蒙古语 http://en.wikipedia.org/wiki/Mongolian_script。问题是传统的蒙古文是从上到下、从左到右垂直书写的。我的问题是如何垂直显示文本并仍然进行换行工作?

如果您耐心听我一分钟,我会尽力更清楚地解释这个问题。下面是我想要实现的文本视图类型的图像。如果外文脚本让您感到困惑,我已经包含了遵循相同模式的英文文本。事实上,如果应用程序有任何英文文本要显示,它应该是这样的。

对于简单的单行 UILabel,顺时针旋转 90 度即可。但是,对于多行 UITextView 我需要处理换行。如果我只是进行简单的 90 度旋转,那么首先写入的内容将出现在最后一行。

到目前为止我已经制定了一个我认为可以解决这个问题的计划:

  1. 制作一种自定义字体,其中所有字母都垂直镜像。
  2. 将文本视图顺时针旋转 90 度。
  3. 水平镜像文本视图。

这应该可以解决文本换行问题。

我可以做镜像字体。但是,我不知道如何对 UITextView 的旋转和镜像进行 Swift 编码。我发现以下链接似乎为解决方案的某些部分提供了提示,但它们都在 Objective C 中,而不是在 Swift 中。

  • 如何围绕自己的中心旋转子视图? https://stackoverflow.com/questions/8777199/how-to-rotate-sub-views-around-their-own-centres
  • 围绕其中心旋转 UIView 并保持其大小 https://stackoverflow.com/questions/21370728/rotate-uiview-around-its-center-keeping-its-size
  • iOS:在屏幕上镜像内容 https://stackoverflow.com/questions/8575064/ios-mirror-content-on-screen
  • 镜像 UIView https://stackoverflow.com/questions/8675867/mirroring-uiview

应用程序商店中有传统的蒙古语应用程序(例如this https://itunes.apple.com/us/app/bainu/id946920834?mt=8 and this https://itunes.apple.com/us/app/boljoo/id741637912?mt=8)但我还没有找到任何人分享他们的源代码,所以我不知道他们在幕后做什么来显示文本。我计划将我的代码开源,以便将来其他人为数百万阅读传统蒙古文的人开发应用程序不再那么困难。您能为这项努力提供的任何帮助,不仅是我,而且是蒙古人民,都将非常感激。即使您不了解自己,对这个问题进行投票以使其更加明显也会有所帮助。

Update

@sangonz 的答案仍然是一个很好的答案,但我暂时将其取消标记为已接受的答案,因为我无法让一切正常工作。具体来说:

  • 启用滚动(通过将自定义视图嵌入滚动视图或通过子类化 UIScrollView https://stackoverflow.com/questions/30620291/how-to-make-a-vertical-uitextview-by-subclassing-it-from-uiscrollview-in-swift)。在 github 项目中,@sangonz 说这应该很容易,但它不适合我。
  • 在方向改变时重新布局(而不是拉伸)字线。我认为通过更多的研究,这个问题应该不难解决。
  • 为什么文本行不一直延伸到视图的边缘?底部有一个很大的缺口。
  • How to unlink the NSTextStorage of the custom vertical view from the other UITextView. (see this question https://stackoverflow.com/questions/30796174/how-to-initialize-nstextstorage-with-a-string-in-swift)

到这一点我一直用的是原来的方法 https://stackoverflow.com/questions/30907710/rotating-a-view-in-layoutsubviews我在上面提出了建议,但我真正想要的是得到像 @sangonz 提议的那样的东西。

我现在也在考虑替代方法,例如

  • 使用核心文本 https://stackoverflow.com/questions/34221708/should-i-use-text-kit-or-lower-level-text-handling-for-a-vertical-text-view、缺点:感觉像是重新发明轮子
  • 使用WebKit https://stackoverflow.com/questions/28544714/how-do-you-make-a-vertical-text-uilabel-and-uitextview-for-ios-in-swift/28694927#comment56465313_28544714,缺点:Apple 不再使用 WebKitUITextView

Edit:这就是我最终做到的。

这是我的 GitHub 中的一个非常基本的实现:垂直文本-iOS https://github.com/sangonz/Vertical-Text-iOS.

没什么特别的,但它确实有效。最后我不得不将 TextKit 和图像处理结合起来。看一下代码。它涉及:

  1. 子类化NSTextContainer以获得正确的文本尺寸。
  2. 创建自定义UIView对每行应用仿射变换并使用渲染来渲染文本NSLayoutManager保留所有 TextKit 功能。

TextKit方式

保留所有原生文本优点(例如突出显示、选择...)的正确方法是使用标准 TextKit API。您提出的方法会破坏所有这些,或者可能会导致奇怪的行为。

然而,看起来 iOS 中的 TextKit 还不支持开箱即用的垂直方向,但它已经为此做好了准备。顺便说一句,在 OS X 中它得到了一定程度的支持,你可以调用textView.setLayoutOrientation(.Vertical),但它仍然有一些局限性。

The NSTextLayoutOrientationProvider协议定义了一个接口 为一致的文本布局提供默认方向 对象,在没有明确的情况下NSVerticalGlyphFormAttributeName属性。实现此接口的唯一 UIKit 类是NSTextContainer,其默认实现返回NSTextLayoutOrientationHorizontal. An NSTextContainer子类 处理垂直文本可以将此属性设置为NSTextLayoutOrientationVertical支持自定义布局 方向逻辑。

Source: UIKit >NSTextLayoutOrientationProvideriOS 协议参考 https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSTextLayoutOrientationProvider_Protocol_TextKit/index.html#//apple_ref/occ/intf/NSTextLayoutOrientationProvider

综上所述,你应该开始子类化NSTextContainer,你将不得不处理NSLayoutManager and NSTextContainer a lot.


自定义图像处理方式

另一方面,如果您决定遵循自定义文本渲染,我建议采用以下方法。

  1. 渲染普通文本到具有普通字体的隐藏层。为其边界框指定正确的大小。
  2. 获取文本属性,主要是文字高度和行距。
  3. 处理图像从下到上以相反的顺序绘制每条线,如下图所示。你应该买一个新的CGImage因此。
  4. 旋转图像创建一个UIImage并设置正确的UIImageOrientation value.
  5. 插入该图像 into a UIScrollView只允许水平滚动。

请注意,此方法会呈现整个文本,因此不要将其用于很长的文本。如果您需要这样做,则需要考虑平铺方法。手表WWDC 2013 > 217 - 探索 iOS 7 上的滚动视图 https://developer.apple.com/videos/wwdc/2013/#217.

祝你好运!

更新:(图片来自github项目)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Swift 中为 iOS 制作垂直文本 UILabel 和 UITextView? 的相关文章

随机推荐

  • 如何设置Android按钮背景颜色?

    我想为几个按钮使用自定义背景颜色 我试过android background cc2 但它取代了整个按钮 因此它看起来不再像一个按钮 显然可以使用
  • HTTP是无状态的,那么keep-alive是什么意思呢?

    Keep Alive 300 Proxy Connection keep alive 我们知道HTTP连接在请求得到响应时关闭 那么这是什么意思keep alive 有人可以详细说明一下吗 这意味着可以保持连接打开以请求更多资源 例如图像和
  • DDD:从哪里获取值对象列表最合适

    我有一个分配给产品的名为 产品类型 的值类型 一种产品有一种产品类型 为了允许用户从列表中选择类型 我将填充一个下拉列表 在哪里检索产品类型列表最合适 实现存储库模式的类 编辑 通过将产品代码更改为产品类型来澄清 产品类型类似于 DVD C
  • PostgreSQL 9.2:citext[] 上的 GIN 索引

    我需要加快这个查询的速度 SELECT FROM mytable WHERE value ANY citext array col LIMIT 1 where citext array col是一个 citext 数组 我尝试创建一个运算符
  • 为什么我的 Django 视图在每个页面视图中都会被点击两次?

    我似乎一辈子都找不到问题所在 非常简单 我有一个从数据库中提取的数据库对象 将其 视图 增加一 然后保存 我的视图显示增加的值 但随后我的日志显示该值再次增加 g Game objects filter slug slug distinct
  • 将dataUrl转换为blob并通过ajax提交

    我正在使用 imgly 图像裁剪器插件 针对我的应用程序稍作修改 它当前将图像转换为dataUrl并将图像输出为 base64 图像 我可以将其另存为 jpeg 我正在努力调整dataURItoBlob找到函数here https stac
  • 无法打开文档“Main.Storyboard”。无法识别的文件内容

    从 Xcode 7 更新到 Xcode 8 后 我无法打开 Storyboard 有人可以帮忙吗 里面没有显示任何错误 对于我来说 将故事板打开为 源代码 修复合并冲突 然后重新启动 Xcode 就完成了这项工作
  • 使用 PHP 将二进制数据插入 SQL Server

    我在 SQL Server 2005 数据库中有一个 varbinary MAX 字段 我试图弄清楚如何使用 PHP 将二进制数据 即图像 插入到该字段中 我使用 ODBC 连接 SQL Server 数据库 我已经看到许多示例解释了如何与
  • Qt平台插件问题Rstudio

    我正在尝试通过 RStudio 绘制 seaborn 热图 I usereticulateR 中的包 下面是我的代码 library reticulate use condaenv python36 conda auto required
  • 如何用CLOB调用REPLACE(不超过32K)

    Oracle 11g 确实提高了 CLOB 的可用性 重载了大多数字符串函数 因此它们现在可以与 CLOB 一起本地工作 然而 一位同事从他的代码中得到了这个错误 ORA 22828 input pattern or replacement
  • 如何对 django url 进行单元测试?

    除了我的应用程序之外 我的应用程序在所有地方都实现了 100 的测试覆盖率urls py 你对我如何写作有什么建议吗有意义的对我的 URL 进行单元测试 FWIW 这个问题是在我尝试测试驱动开发时出现的 并且希望在编写代码来修复它们之前失败
  • 如何通过已知路由器上的三角测量来确定我的位置?

    有没有可用的开源软件 基本上 我只想根据位置固定且已知的路由器的信号强度进行三角测量 我意识到可能存在干扰的情况 但我们还是坚持列出已知的源代码 谢谢 我不知道任何三边测量软件 有人应该编写一个开源库 看看三边测量 http en wiki
  • 错误 NETSDK1064:找不到软件包 DnsClient,1.2.0

    我有一个 Asp Net core docker 镜像 我上次尝试构建它是两个月前 现在 我在尝试构建它时遇到错误 有任何想法吗 是不是有什么东西破坏了 Microsoft docker 镜像 当尝试在 Elasticbeanstalk 实
  • Python“数组索引太多”

    我正在使用 pandas 读取 python 中的文件 然后将其保存在 numpy 数组中 该文件的尺寸为 11303402 行 x 10 列 我需要拆分数据以进行交叉验证 为此我将数据切片为 11303402 行 x 9 列的示例和 1
  • 在 Cython 类中,使用 __init__ 和 __cinit__ 有什么区别?

    代码块1使用 init cython 3 cdef class c cdef int a str s def init self self a 1 self s abc def get vals self return self a sel
  • 服务器使用 HTTP Keep-Alive 与客户端通信

    最近在一次采访中 我被问到如何处理在线聊天客户端应用程序 我经历了标准的 轮询 解决方案 但被打断了 因为面试官正在寻找 HTTP 1 1 keep alive 方法 使用 HTTP 相当长一段时间并记住重点是 无状态 这对我来说从来没有发
  • 无法对测试运行“xxxx 2011-10-20 13:00:00”进行排队。您没有执行该操作的适当权限

    我正在尝试在 C VS2010 中运行我的测试用例 但突然有一天 它开始向我展示无法对测试运行 xxxx 2011 10 20 13 00 00 进行排队 您没有执行该操作的适当权限 错误 虽然我通过我的测试进行了调试 但无法选择并运行它
  • 如果连接丢失,从 SQL Server 到 Oracle 服务器的 OpenQuery 将无限期挂起

    我有一个在 SQL Server 2005 数据库上运行的计划作业 它运行一个从视图导入数据的存储过程 该视图由一个OPENQUERY到链接的 Oracle 服务器 我无法控制 Oracle 服务器 它在地理上和虚拟上都与 Sql Serv
  • 如何重命名本地 Git 分支?

    如何重命名尚未推送到远程存储库的本地分支 Related 重命名本地和远程 Git 存储库的 master 分支 https stackoverflow com questions 1526794 rename master branch
  • 如何在 Swift 中为 iOS 制作垂直文本 UILabel 和 UITextView?

    如果您根据标题提出这个问题 但对蒙古语不感兴趣 您可能会寻找以下问答 Swift 如何旋转 UIButton 和 UILabel 的文本 https stackoverflow com questions 28717634 swift ho