当前位置: 首页 > 知识库问答 >
问题:

如何在Swift中为iOS创建垂直文本UILabel和UITextView?

南门峰
2023-03-14

如果你是根据题目来回答这个问题的,但对蒙古语不感兴趣,你可能会寻找这个问题

  • Swift:如何旋转UIButton和UILabel的文本?

我一直在学习Swift,以便为传统蒙古语开发iOS应用程序。问题是传统蒙古语是从上到下、从左到右垂直书写的。我的问题是,如何在垂直显示文本的同时仍进行换行工作?

如果你跟我呆一会儿,我会尽量把问题解释得更清楚。下面是我想要实现的文本视图的图片。如果外文脚本让你不感兴趣,我已经加入了遵循相同模式的英文文本。事实上,如果应用程序有任何英文文本显示,这就是它的外观。

对于简单的单线UILabel,顺时针旋转90度即可。但是,对于多行UITextView,我需要处理换行。如果我只是做一个普通的90度旋转,写的第一件事将结束在最后一行。

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

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

这应该会处理文本换行。

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

  • 如何围绕自己的中心旋转子视图
  • 围绕其中心旋转UIView,保持其大小
  • iOS:在屏幕上镜像内容
  • 镜像UIView

app store中有一些传统的蒙古语应用(比如这个和这个),但我还没有找到任何人分享他们的源代码,所以我不知道他们在幕后做什么来显示文本。我计划让我的代码开源,这样将来其他人就不难为数百万阅读传统蒙古语的人开发应用程序了。我和蒙古人民都将非常感谢你们为这项工作提供的任何帮助。即使你不了解自己,将这个问题向上投票以使其更明显也会有所帮助。

@sangonz的答案仍然是一个很好的答案,但是我暂时没有把它标记为被接受的答案,因为我只是不能让一切都起作用。具体而言:

  • 启用滚动(通过在scrollview中嵌入自定义视图或通过将UIScrollView子类化)。在github项目中,@sangonz说这应该很容易,但这不适合我
  • 在方向改变时重新排列(而不是拉伸)单词行。我认为这应该不难通过更多的研究来解决
  • 为什么文本行不一直延伸到视图的边缘?底部有一个很大的缺口
  • 如何将自定义垂直视图的NSTextStorage与其他UITextView解除链接 (见此问题)

到目前为止,我一直在使用我在上面提出的原始方法,但我真正想要的是让@sangonz提出的方法起作用。

我现在也在考虑其他方法,比如

  • 使用Core Text,缺点:感觉像是重新发明轮子
  • 使用WebKit,缺点:苹果不再使用WebKit为他们的UITextView

共有2个答案

何修能
2023-03-14

如果要旋转文本,我建议使用从右到左的布局,这样可以跳过镜像步骤(只需以另一种方式旋转)。

您应该能够只设置label/textview的transform属性:

view.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(CGFloat(-M_PI_2)), view.bounds.width, view.bounds.height)

旋转后需要平移,因为视图围绕其原点旋转(在左上角)。

好消息是,手势和点击会在像素转换的同时进行,所以控件会继续按照您期望的方式工作。

黄淇
2023-03-14

编辑:这就是我最终做到的。

在我的GitHub中有一个非常基本的实现:垂直文本iOS。

没什么花哨的,但很有效。最后我不得不混合TextKit和图像处理。看看代码。它涉及:

  1. 子类化NSTextContainer,以获得正确的文本维度

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

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

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

资料来源:UIKit

总之,您应该开始子类化NSTextContainer,并且您将不得不处理很多NSLayoutManagerNSTextContainer

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

  1. 使用普通字体将普通文本渲染到隐藏层。为其边界框指定正确的大小

请注意,此方法渲染整个文本,因此不要将其用于很长的文本。如果你需要这样做,你需要考虑一个贴砖方法。观看WWDC 2013

祝你好运

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

 类似资料:
  • 问题内容: 我试图找到最有效的方法来使div对齐文本。我尝试了几件事,但似乎都没有用。 问题答案: 对于CSS 2浏览器,可以使用/ 来使内容居中。 jSFiddle提供了一个示例: 可以将旧浏览器(Internet Explorer 6/7)的hack合并为样式,并用于从较新的浏览器中隐藏样式:

  • 我想知道如何在flatter中垂直和水平地将文本小部件的内容居中。我只知道如何使用将小部件本身居中,而不知道内容本身。默认情况下,它与左侧对齐。在Android中,我相信实现这一点的TextView的属性称为。 我想要的示例:

  • 问题内容: 目标:纯Canvas上的Android> = 1.6。 假设我想编写一个函数,该函数将绘制一个(宽度,高度)大的红色矩形,然后在其中绘制一个黑色的 Hello World 文本。我希望文本在视觉上位于矩形的中心。因此,让我们尝试: 现在,我不知道要在drawText的参数中加上标记的内容,即我不知道如何垂直对齐文本。 就像是 ???? = topLeftY + height / 2 +

  • 问题内容: 我希望在游戏中(SpriteKit)中创建带有按钮和图像的商店,但我需要使这些物品能够滚动,以便玩家可以上下滚动商店(就像UITableView一样,但每个商店中都有多个SKSpriteNodes和SKLabelNodes细胞)。知道如何在SpriteKit中做到这一点吗? 问题答案: 正如所答应的第二个答案,我只是想出了问题。 我建议始终从gitHub项目中获取此代码的最新版本,以防

  • 如图所示,我有代码在屏幕上绘制文本。textalign函数仅支持水平对齐。现在,我要添加对垂直对齐的支持。有人能帮我一下吗? 代码

  • 问题内容: 如何在VC中获取上/下滚动/滑动方向? 我想在我的VC中添加UIScrollView或其他内容,以查看用户是否向上/向下滑动/滚动,然后隐藏/显示依赖项(如果是向上/向下手势)。 问题答案: 如果您使用,则可以从该功能中受益。您需要通过以下方式保存它的最后一个位置()并更新它: 当然还有其他方法可以做到这一点。 希望对您有所帮助。