16

Background

I'm new to iOS development, but in order start making even the most rudimentary apps using the vertical Mongolian script, I need to have a vertical UITextView. I haven't found any other Mongolian app developers sharing their code so I am trying to make it myself. Mongolian is written from top to bottom and lines wrap from left to right as is illustrated in the following graphic:

enter image description here

Scrolling should be horizontal (left to right).

In a previous question I proposed a combination of a mirrored font and a rotation and mirroring of the UITextView (because that is what I had done in Android). However, after reading this answer and doing further research into the iOS way of doing things (like using TextKit), I'm thinking it may be better to just create something like UIVerticalTextView from scratch rather than messing with the normal UITextView. And since I see that UITextView inheirits from UIScrollView, I assume I should subclass UIScrollView to make the UIVerticalTextView.

Where I am at now

The answer I mentioned above subclassed UIView but I was having a lot of trouble getting scrolling to work. This is another reason I want to subclass UIScrollView. Also that solution did not relayout the words in each line when there was an orientation change.

I've gathered the following pieces but I'm not sure how to put them together:

  • NSTextStorage - There shouldn't be anything different with this. It will just store the Mongolian Unicode text and any styling information.
  • NSTextContainer - The height and the width need to be switched to give the vertical text container size. (I think so, anyway. Unless this can be done somewhere else.)
  • NSLayoutManager - Does anything special need to be done here or is that taken care of by the UIVerticalTextView?
  • UIVerticalTextView - This will be a subclass of UIScrollView but what are the methods that need to be added and/or overridden?

    class UIVerticalTextView: UIScrollView {
    
        // Which properties to include?
        //     - TextStorage
        //     - TextContainer
        //     - LayoutManager
    
        // which methods to override?
    
        // which methods to add to give minimal functionality like UITextView?
        //     - init
        //     = text
    }
    

Updates

These questions are attempts to break the problem down into smaller pieces:

And trying with a different approach:

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • How do you want to display the characters? Do you have a font? – Nils Ziehn Jun 03 '15 at 12:44
  • @NilsZiehn Yes, I have a font with the Mongolian glyphs. For the sake of simplicity, though, you can assume that only English needs to be displayed. – Suragch Jun 03 '15 at 12:48
  • What issues did you have with CGAffineTransformMakeRotation? I was digging through your related questions and saw that you had played around with this. – Will M. Jun 09 '15 at 19:15
  • @WillM. Yes, [here](http://stackoverflow.com/a/28717635/3681880) I did. My main problem with this is that autolayout doesn't work well anymore after a rotation. Although I personally haven't gotten it work yet, I know some people have been successful in surrounding the rotated view with a container view and then applying autolayout to the container view. However, because `UITextView` is such a basic component, I would like to develop a vertical UITextView to share with other Mongolian developers, one which doesn't require any extra tricks to make it work. – Suragch Jun 10 '15 at 02:59
  • have you created a git repo so if someone want help can fork and make change ? and in manoglian script scroll should be top to bottom or left to right ? – Varun Naharia Jun 11 '15 at 14:53
  • @VarunNaharia I don't have a git repo yet, but I plan to in the future. Scroll should be left to right. – Suragch Jun 12 '15 at 03:20
  • creating git repo won't take much time, anyway nice project – Varun Naharia Jun 12 '15 at 03:36

1 Answers1

5

If you have a font that displays your text the easiest way would be to use the normal UITextView:

UITextView *textView = [[UITextView] alloc] init];

textView.transform = CGAffineTransformMakeRotation(-M_PI/2);

textView.text = @"YOUR TEXT HERE";

[textView setBaseWritingDirection:UITextWritingDirectionRightToLeft forRange:[textView textRangeFromPosition:[textView beginningOfDocument] toPosition:[textView endOfDocument]]];

The textView will now scroll to the right not down, I assume that is supposed to happen for mongolian?

Nils Ziehn
  • 4,118
  • 6
  • 26
  • 40
  • 1
    You're correct in assuming that horizontal scrolling is needed. However, right-to-left layouts are designed for Arabic, Hebrew, and other RTL languages. These languages are actually bidirectional because numbers and English (and Mongolian) words which are embedded in the text are still written LTR. And even if it were truly RTL, the words would be spelled backwards and for Mongolian the glyphs would not match to the next letter (unless I used a horizontally mirrored font). – Suragch Jun 03 '15 at 12:55
  • Another problem I have experienced when trying to do a rotation is that layout gets very tricky. – Suragch Jun 03 '15 at 12:58
  • Unfortunately I don't really get your point why you would have to invert your glyphs, because arabic letters are not mirrored when displayed, right? (If they are, I get your point..). Can you show me a screenshot what the result is when you just use a normal UITextView with UITextWritingDirectionRightToLeft ? (and how it's supposed to look like in comparison) – Nils Ziehn Jun 03 '15 at 13:06
  • After we've figured out the previous problem: The layout problem can be handled easily if you just use a UIView as a container and use the normal layout constraints for this view. Then you create a subview for this view in code and use the 'oldschool' autoresizingmasks 'flexibleWidth' and 'flexibleHeight' to make the UITextView adapt to the rect of the containing UIView. Then you won't have any problems! – Nils Ziehn Jun 03 '15 at 13:08
  • 1
    Characters are displayed LTR or RTL depending on their Unicode values. If English (or Mongolian) were written in a UITextView with UITextWritingDirectionRightToLeft then each line would just look right aligned rather than each character actually being written from right to left. Arabic, though, would have each character written RTL. I don't have a screenshot available but there are some good images [here](http://rishida.net/docs/unicode-tutorial/part4). See [here](http://en.wikipedia.org/wiki/Bi-directional_text) also. – Suragch Jun 03 '15 at 13:31
  • Since up to now I have still been unsuccessful in subclassing UIScrollView I am looking more into your suggestion of using a container view for the rotated view. I opened a [separate question here](http://stackoverflow.com/questions/30841064/are-rotated-views-compatible-with-auto-layout). I was trying with Auto Layout but is it only the "old school" methods that work? – Suragch Jun 15 '15 at 11:19
  • Autolayout with transform property has never really worked for me to be honest! – Nils Ziehn Jun 16 '15 at 11:43
  • You should use layout masks, then set the transform, then set the frame to values you expect AFTER the rotation (this means you can just set subview.frame = subview.superview.bounds) – Nils Ziehn Jun 16 '15 at 11:45
  • Although your answer did not solve the problem, no one else even attempted to answer. Also your comments about "old school" layout and using a `UIView` container were useful in pointing me back in [another direction](http://stackoverflow.com/a/30952595/3681880). Thank you. I'm awarding you the bounty. – Suragch Jun 22 '15 at 11:21