> Swift: How can you rotate text for UIButton and UILabel?
我一直在学习Swift为了开发iOS应用程序traditional Mongolian.问题是,传统的蒙古语是从顶部到底部和从左到右垂直写。我的问题是如何垂直显示文本,仍然有线包装工作?
如果你和我呆在一起,我会尝试更清楚地解释这个问题。下面是我想实现的那种文本视图的图像。如果外国脚本抛出你,我已经包括遵循相同的模式的英语文本。事实上,如果应用程序有任何英语文本显示,这是它应该是什么样子。
对于简单的单线UILabel,90度顺时针旋转将工作。然而,对于多行UITextView我需要处理行换行。如果我只是做一个简单的90度旋转,写的第一件事将最终在最后一行。
到目前为止,我已经制定了一个计划,我认为可以克服这个问题:
>制作一个自定义字体,其中所有字母都垂直镜像。
>将文本视图顺时针旋转90度。
>水平镜像文本视图。
这应该照顾文本wrap。
我可以做镜像字体。然而,我不知道如何做的Swift编码的旋转和镜像的UITextView。我发现以下链接似乎给解决方案的部分提示,但他们都在Objective C而不是在Swift。
> How to rotate sub-views around their own centres?
> Rotate UIView around its center keeping its size
> iOS: Mirror content on screen
> Mirroring UIView
在应用商店中有传统的蒙古应用程序(如this和this),但我还没有发现有谁正在分享他们的源代码,所以我不知道他们在幕后做什么来显示文本。我打算让我的代码开源,所以它不是那么难以为未来的人开发应用程序的几百万人阅读传统蒙古人。任何帮助,你可以给这项努力将不胜感激,不仅是我,而且蒙古人民。即使你不知道自己,upvoting这个问题,使其更加明显将有所帮助。
更新
@ sangonz的答案仍然是一个很好的答案,但我暂时取消标记为接受的答案,因为我只是不能得到一切工作。特别:
>启用滚动(通过在scrollview中嵌入自定义视图或通过subclassing UIScrollView)。在github项目中,@sangonz说这应该很容易,但它不是为我。
>在方向变化时获得字线的重新布局(而不是拉伸)。我认为这不应该太难解决与一点更多的研究。
>为什么文本行不会一直到视图的边缘?底部有一个很大的差距。
>如何取消自定义垂直视图的NSTextStorage与其他UITextView的链接。 (见this question)
到这一点I have been using the original method我上面提出,但我真正想要的是得到一些像@sangonz建议工作。
我现在也考虑替代方法
> Using Core Text,缺点:感觉像重塑轮子
> Using WebKit,缺点:苹果不再使用WebKit为他们的UITextView
这里是一个非常基本的实现在我的GitHub:Vertical-Text-iOS。
没有什么花哨,但它的工作原理。最后我不得不混合使用TextKit和图像处理。看看代码。它涉及:
>将NSTextContainer子类化以获取正确的文本维度。
>创建自定义UIView以渲染文本,对每一行应用仿射变换,并使用NSLayoutManager进行渲染以保留所有TextKit特性。
TextKit方式
保持所有原生文本优点(例如突出显示,选择…)的正确方法是使用标准的TextKit API。你提出的方法将打破所有这一切,或可能会导致奇怪的行为。
但是,看起来像iOS的TextKit不支持垂直方向的开箱即用,但它已经准备好了。作为旁注,在OS X它有点支持,你可以调用textView.setLayoutOrientation(.Vertical),但它仍有一些限制。
The
NSTextLayoutOrientationProvider
protocol defines an interface
providing the default orientation for text laid out in a conforming
object,in absence of an explicitNSVerticalGlyphFormAttributeName
attribute. The only UIKit class that implements this interface is
NSTextContainer
,whose default implementation returns
NSTextLayoutOrientationHorizontal
. AnNSTextContainer
subclass that
handles vertical text could set this property to
NSTextLayoutOrientationVertical
to support the custom layout
orientation logic.
资料来源:UIKit > NSTextLayoutOrientationProvider
Protocol Reference for iOS
总而言之,你应该开始对NSTextContainer进行子类化,你必须处理NSLayoutManager和NSTextContainer。
自定义图像处理方式
>使用正常字体将正常文本渲染到隐藏图层。给它正确的大小到它的边框。
>获取文本属性,主要是文本高度和行间距。
>从底部到顶部以相反的顺序处理图像,绘制每一行,如下图所示。你应该得到一个新的CGImage结果。
>旋转图像创建UIImage并设置正确的UIImageOrientation值。
>将该图像插入到只允许水平滚动的UIScrollView中。
当心这个方法呈现整个文本,所以不要使用它很长的文本。如果你需要这样做,你将需要考虑一个平铺的方法。手表WWDC 2013 > 217 – Exploring Scroll Views on iOS 7。
祝你好运!
更新:(从github项目的图像)