If you came to this question based on the title but are not interested in Mongolian, you might be looking for this Q&A instead:
Edit: This is how I finally did it.
Here's a very basic implementation in my GitHub: Vertical-Text-iOS.
Nothing fancy, but it works. Finally I had to mix TextKit and image processing. Take a look at the code. It involves:
NSTextContainer
to get the right text dimensions.UIView
to render the text applying affine transformations to each line and rendering using NSLayoutManager
to keep all TextKit features.The proper way to keep all native text benefits (e.g. highlighting, selection...) is to use standard TextKit APIs. The method you are proposing would break all that or would possibly result in strange behaviour.
However, looks like TextKit in iOS does not support vertical orientation out-of-the-box yet, but it is prepared for that. As a side note, in OS X it is somewhat supported and you could call textView.setLayoutOrientation(.Vertical)
, but it still has some limitations.
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 isNSTextContainer
, whose default implementation returnsNSTextLayoutOrientationHorizontal
. AnNSTextContainer
subclass that handles vertical text could set this property toNSTextLayoutOrientationVertical
to support the custom layout orientation logic.
Source: UIKit > NSTextLayoutOrientationProvider Protocol Reference for iOS
In conclusion, you should start subclassing NSTextContainer
, and you will have to deal with NSLayoutManager
and NSTextContainer
a lot.
If, on the other hand you decide to follow your custom text rendering I suggest the following approach.
CGImage
as a result.UIImage
and setting the correct UIImageOrientation
value.UIScrollView
that only allows horizontal scrolling.Beware this method renders the whole text, so don't use it for very long texts. If you need to do that, you will need to consider a tiling approach. Watch WWDC 2013 > 217 - Exploring Scroll Views on iOS 7.
Good luck!
Update: (image from github project)
If you're going to rotate the text I would suggest using a right-to-left layout so that you can skip the mirroring step (and just rotate the other way).
You should be able to just set the label/textview's transform
property:
view.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(CGFloat(-M_PI_2)), view.bounds.width, view.bounds.height)
You need to translate after you rotate because the view rotates around its origin (in the upper left).
The good news is that gestures and taps are transformed at the same time the pixels are, so controls continue to work the way you expect them to.