Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a vertical UITextView by subclassing it from UIScrollView in Swift?

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:

  • How to make UITextView from scratch?
  • How to Initialize NSTextStorage with a String in Swift

And trying with a different approach:

  • Are rotated Views compatible with Auto Layout?
  • Rotating a view in layoutSubviews This actually has a working solution now. However, it basically involves stacking three views on top of each other. I would still prefer to make a custom UIScrollView subclass that uses TextKit as I have presented in my current question.
like image 231
Suragch Avatar asked Jun 03 '15 12:06

Suragch


1 Answers

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?

like image 181
Nils Ziehn Avatar answered Nov 01 '22 09:11

Nils Ziehn