カスタムUIView
の角の丸みとテキストの背景色に関する質問があります。
基本的に、カスタムUIViewで次のような効果を実現する必要があります(添付画像-片側の丸い角に注意してください):
私は使用するアプローチは次のように考えています:
ただし、これが唯一の解決策であるかどうか(または、これが最も効率的な解決策であるかどうか)はわかりません。
UIWebView
の使用はオプションではないため、カスタムUIView
で行う必要があります。
私の質問は、これが使用するための最良のアプローチであり、私は正しい軌道に乗っていますか?それとも、重要な何かを見逃したり、間違った方法で進んでいますか?
私は上記の効果を達成することができたので、同じことに対する答えを投稿すると思いました。
これをより効果的にするための提案があれば、遠慮なく投稿してください。あなたの答えを正しいものとしてマークします。 :)
これを行うには、NSAttributedString
に「カスタム属性」を追加する必要があります。
基本的に、それはNSDictionary
インスタンスに追加できるものであれば、任意のキーと値のペアを追加できるということです。システムがその属性を認識しない場合、何もしません。その属性のカスタム実装と動作を提供するのは、開発者としてのあなた次第です。
この回答の目的のために、_@"MyRoundedBackgroundColor"
_という値を持つ_[UIColor greenColor]
_というカスタム属性を追加したと仮定します。
以下の手順では、CoreText
がどのように処理を行うかについての基本的な理解が必要です。 Appleのコアテキストプログラミングガイド フレーム/ライン/グリフラン/グリフなどを理解するには.
そのため、手順は次のとおりです。
NSAttributedString
を受け入れるためのプロパティがあります。CTFramesetter
インスタンスを使用してNSAttributedString
を作成します。drawRect:
_メソッドをオーバーライドしますCTFrame
。からCTFramesetter
インスタンスを作成しますCGPathRef
を作成するには、CTFrame
を指定する必要があります。 CGPath
が、テキストを描画するフレームと同じになるようにします。CTFrameGetLines(...)
を使用して、作成したCTFrame
のすべての行を取得します。CTFrameGetLineOrigins(...)
を使用して、CTFrame
のすべての行の原点を取得します。for loop
_を開始します-CTLine
...の配列の各行に対して.CGContextSetTextPosition(...)
を使用して、テキスト位置をCTLine
の先頭に設定します。CTLineGetGlyphRuns(...)
を使用すると、CTRunRef
からすべてのグリフ実行(CTLine
)を取得できます。for loop
_を開始します-CTRun
...の配列内の各glyphRunに対して.CTRunGetStringRange(...)
を使用して実行範囲を取得します。CTRunGetTypographicBounds(...)
を使用して活版印刷の境界を取得します。CTLineGetOffsetForStringIndex(...)
を使用して、実行のxオフセットを取得します。runBounds
と呼びましょう)。CTRunGetTypographicBounds(...)
は、テキストの「上昇」と「下降」を保存するための変数へのポインターを必要とします。ランの高さを取得するにはこれらを追加する必要があります。CTRunGetAttributes(...)
を使用して実行の属性を取得します。runBounds
)。runBounds
ができたので、ペイントしたい領域がわかりました-CoreGraphis
/UIBezierPath
メソッドのいずれかを使用して、特定の四角形を描画して塗りつぶすことができます丸い角。UIBezierPath
には_bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
_と呼ばれる便利なクラスメソッドがあり、特定のコーナーを丸めることができます。 2番目のパラメーターでビットマスクを使用してコーナーを指定します。CTRunDraw(...)
を使用してグリフランを描画するだけです。属性範囲が複数の実行にまたがることを検出することに関して、最初の実行で属性に遭遇したときにカスタム属性の有効範囲全体を取得できます。属性の最大有効範囲の長さが実行の長さよりも長い場合、右側に鋭い角をペイントする必要があります(左から右のスクリプトの場合)。さらに数学を使用すると、次の行のハイライトコーナースタイルも検出できます。 :)
効果のスクリーンショットが添付されています。上部のボックスは標準のUITextView
であり、そのためにattributedTextを設定しました。下部のボックスは、上記の手順を使用して実装されたものです。同じ属性文字列が両方のtextViewに設定されています。
繰り返しますが、私が使用したものよりも良いアプローチがあれば、教えてください! :D
これがコミュニティに役立つことを願っています。 :)
乾杯!