3

Languages such as Japanese or Chinese can be written vertically, starting from the top right of the page, going down, and when you reach the bottom, you go up and go to the next line on the left.

NSTextView seems to support this out of the box with

textView.setLayoutOrientation(.vertical)

There is also a storyboard option.

While this seems to work for a single text view (the text does begin on the top right of the text view), it doesn't work when I try to make the text view scrollable, putting the text view inside a scroll view.

For example, when I tried to add a "Scrollable Text View" in the storyboard, the NSTextView doesn't fill the whole scroll view for some reason, as indicated by the little white squares in the picture:

enter image description here

(Note that the only constraints I added was pinning the four edges of the scroll view to the window)

This is undesirable. The text view should fill the whole scroll view, so that the text begins on the very right of the window. The text view doesn't expand to the at all when I drag the right side of the window to expand it.

enter image description here

The text view only expands when I enter more text in it.

None of these behaviours can be seen if the text view has horizontal orientation.

What am I doing wrong? Is scrollable vertical text just not supported?


I've also tried adding the text view programmatically, but the same behaviour shows up

let scrollView = NSTextView.scrollableTextView()
view.addSubview(scrollView)

scrollView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    scrollView.topAnchor.constraint(equalTo: view.topAnchor),
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
    scrollView.leftAnchor.constraint(equalTo: view.leftAnchor),
    scrollView.rightAnchor.constraint(equalTo: view.rightAnchor),
])

let textView = scrollView.documentView as! NSTextView

textView.textStorage?.setAttributedString(
    NSAttributedString(string: "あいうえおかきくえこ", attributes: [
        .font: NSFont.systemFont(ofSize: 25),
        .foregroundColor: NSColor.textColor
    ])
)

textView.setLayoutOrientation(.vertical)
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Related: [How to set the default writing direction for NSTextView?](https://stackoverflow.com/questions/30834564/how-to-set-the-default-writing-direction-for-nstextview) – Willeke Jul 07 '22 at 10:54
  • @Willeke I don't think the text *orientation* (horizontal or vertical) is related to the *direction* of the text (left-to-right or right-to-left) because when I tried to change the text direction from "Natural" to "Right to Left", the alignment of the text is unexpectedly aligned against the bottom, rather than the top. Also, punctuation such as "。" or "、" are placed in the wrong place for some reason. Therefore I think for vertical text, the text direction is supposed to be set to "Natural" or "Left to Right" (even though the text is read vertically from the right lol). – Sweeper Jul 07 '22 at 11:04
  • Are the characters rotated? – Willeke Jul 07 '22 at 11:09
  • @Willeke No, the characters are not rotated when using any combination of text orientation and text direction, as is expected of Japanese text. On the other hand, if you write latin letters in the vertical orientation, they will be rotated. – Sweeper Jul 07 '22 at 11:13
  • What are the values of `isHorizontallyResizable` and `isVerticallyResizable`? – Willeke Jul 07 '22 at 11:13
  • @Willeke `Horizontally` is true and `Vertically` is false. I've also tried setting them to be the other way round, and the result is the same. :( As far as I know (correct me if I'm wrong), those properties relate to which way it resizes when there are too much text inside it, but in my case, I want it to expand to use the full width of the scroll view even when there are too little text. – Sweeper Jul 07 '22 at 11:19
  • It looks like a bug to me. The width of the clip and text views is the same as the height. – Willeke Jul 07 '22 at 21:49
  • @Willeke indeed the width and height are the same. I’ll try updating my macOS tomorrow and see I’m lucky :) – Sweeper Jul 07 '22 at 21:51

1 Answers1

0

Think of everything in horizontal layout first. Then rotate the entire textview by 90 degrees clockwise by setLayoutOrientation(.vertical). Then the vertical version of the font, if exists, replaces the corresponding horizontal version where right-up glyphs (most CJK ideographs, full-width alphanumerics, emojis etc.) are rotated 90 degrees counterclockwise, while the remaining glyphs are kept sideway. So, vertically top to bottom and right to left is equivalent to (rotated) horizontally left to right and top to bottom. Everything else is transformed in a similar way: the top/bottom/left/right edges in the (fake) vertical layout is actually left/right/bottom/top edges in the original horizontal layout; the horizontal scroll in the (fake) vertical layout is indeed vertical scroll in the original horizontal layout. In most cases where vertical layout is not specifically mentioned in the documentation, you should assume the terms all refer to the original horizontal layout.