46

タイトルに基づいてこの質問に来たが、モンゴル語に興味がない場合は、代わりにこの Q&A を探している可能性があります。


伝統的なモンゴル語の​​ iOS アプリを開発するために Swift を学習しています。問題は、伝統的なモンゴル語が上から下、左から右に縦に書かれていることです。私の質問は、テキストを垂直に表示し、行の折り返しが機能するようにするにはどうすればよいですか?

1 分間お付き合いいただければ、問題をより明確に説明できるように努めます。以下は、私が達成したいテキストビューの種類の画像です。外国語のスクリプトにうんざりした場合に備えて、同じパターンに沿った英語のテキストを含めました。実際、アプリに表示する英語のテキストがある場合は、このように表示されます。

ここに画像の説明を入力

単純な 1 行の UILabel の場合、時計回りに 90 度回転すると機能します。ただし、複数行の UITextView の場合、行の折り返しを処理する必要があります。単純に 90 度回転させると、最初に書かれたものが最後の行になってしまいます。

これまでのところ、この問題を克服できると思われる計画を立てました。

  1. すべての文字が垂直方向に反転するカスタム フォントを作成します。
  2. テキスト ビューを時計回りに 90 度回転します。
  3. テキスト ビューを水平方向にミラーリングします。

ここに画像の説明を入力

これでテキストの折り返しが処理されます。

ミラーフォントができます。ただし、UITextView の回転とミラーリングのために Swift コーディングを行う方法がわかりません。ソリューションの一部にヒントを与えると思われる次のリンクを見つけましたが、それらはすべて Objective C にあり、Swift にはありません。

アプリ ストアには伝統的なモンゴル語の​​アプリ (これこれなど) がありますが、ソース コードを共有している人をまだ見つけていないため、テキストを表示するために舞台裏で何をしているのかわかりません。伝統的なモンゴル語を読む数百万人の人々のためのアプリを開発するのが将来、それほど難しくないように、私は自分のコードをオープンソースにするつもりです。私だけでなく、モンゴルの人々も、この努力にあなたが与えることができるどんな支援も大いに感謝します. 自分のことを知らない場合でも、この質問に賛成票を投じて、より目立つようにすることが役立ちます.

アップデート

@sangonzの答えはまだ素晴らしい答えですが、すべてを機能させることができなかったため、受け入れられた答えとして一時的にマークを外しました。具体的には:

  • スクロールを有効にする (スクロールビューにカスタム ビューを埋め込むか、UIScrollView をサブクラス化することにより)。github プロジェクトで、@sangonz はこれは簡単なはずだと言いましたが、私には合いませんでした。
  • 向きの変更時にワード ラインの (ストレッチではなく) 再レイアウトを取得します。これは、もう少し研究すれば解決するのはそれほど難しいことではないと思います。
  • テキスト行がビューの端まで届かないのはなぜですか? 底に大きな隙間があります。
  • カスタム垂直ビューの NSTextStorage を他の UITextView からリンク解除する方法。この質問を参照してください)

この時点まで、私は上で提案した元の方法を使用してきましたが、私が本当に望んでいるのは、@sangonz が提案したようなものを機能させることです。

私は現在、次のような代替方法も検討しています

4

2 に答える 2

21

編集:これが私が最終的にやった方法です。

これが私の GitHub の非常に基本的な実装です: Vertical-Text-iOS

派手なことは何もありませんが、うまくいきます。最後に、TextKit と画像処理を組み合わせる必要がありました。コードを見てください。それには以下が含まれます:

  1. NSTextContainer適切なテキストの寸法を取得するためのサブクラス化。
  2. UIView各行にアフィン変換を適用してテキストをレンダリングするカスタムを作成し、NSLayoutManagerすべての TextKit 機能を保持するために使用してレンダリングします。

TextKit の方法

すべてのネイティブ テキストの利点 (強調表示、選択など) を維持する適切な方法は、標準の TextKit API を使用することです。あなたが提案している方法は、それをすべて壊すか、奇妙な動作を引き起こす可能性があります。

ただし、iOS の TextKit は、すぐに使用できる垂直方向をまだサポートしていないようですが、そのために準備されています。補足として、OS X ではある程度サポートされており、 を呼び出すことができますtextView.setLayoutOrientation(.Vertical)が、まだいくつかの制限があります。

このプロトコルは、明示的な 属性NSTextLayoutOrientationProviderがない場合に、適合オブジェクトに配置されるテキストのデフォルトの向きを提供するインターフェイスを定義します。NSVerticalGlyphFormAttributeNameこのインターフェイスを実装する唯一の UIKit クラスは NSTextContainerであり、そのデフォルトの実装は を返します NSTextLayoutOrientationHorizontalNSTextContainer縦書きテキストを処理 するサブクラスは、このプロパティを に設定NSTextLayoutOrientationVerticalして、カスタム レイアウトの向きのロジックをサポートできます。

ソース: UIKit > NSTextLayoutOrientationProvideriOS のプロトコル リファレンス

結論として、サブクラス化を開始する必要があり、多くのNSTextContainerことに対処する必要があります。NSLayoutManagerNSTextContainer


カスタム画像処理方法

一方、カスタム テキスト レンダリングに従うことにした場合は、次のアプローチをお勧めします。

  1. 通常のフォントを使用して、通常のテキストを非表示レイヤーにレンダリングします。境界ボックスに正しいサイズを指定します。
  2. 主にテキストの高さと行間隔のテキスト プロパティを取得します。
  3. 下の画像でわかるように、各行を下から上に逆の順序で描画する画像を処理します。CGImageその結果、新しいものを取得する必要があります。
  4. イメージを回転させてを作成しUIImage、正しいUIImageOrientation値を設定します。
  5. その画像をUIScrollView水平スクロールのみを許可するに挿入します。

このメソッドはテキスト全体をレンダリングするので、非常に長いテキストには使用しないでください。それを行う必要がある場合は、タイリング アプローチを検討する必要があります。WWDC 2013 > 217 - iOS 7 でのスクロール ビューの探索 をご覧ください。

この画像

幸運を!

更新: (github プロジェクトの画像)

ここに画像の説明を入力

于 2015-02-24T11:43:56.993 に答える
4

テキストを回転する場合は、右から左へのレイアウトを使用して、ミラーリングの手順をスキップできるようにすることをお勧めします (逆方向に回転するだけです)。

transformラベル/テキストビューのプロパティを設定するだけでよいはずです:

view.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(CGFloat(-M_PI_2)), view.bounds.width, view.bounds.height)

ビューは原点 (左上) を中心に回転するため、回転後に平行移動する必要があります。

幸いなことに、ジェスチャとタップはピクセルと同時に変換されるため、コントロールは期待どおりに機能し続けます。

于 2015-02-24T12:53:46.320 に答える