非表示領域の設定と表示形状の変更
非表示領域の設定と表示形状の変更
テキストコンテナには、非表示領域を指定できます。非表示領域はUIBezierPathを利用して設定するため、任意の形状を非表示にすることが可能です。また、1つのテキストコンテナ内に複数の非表示領域を設定することもできます。
非表示領域の設定は、exclusionPathsプロパティを使用します。exclusionPathsはNSArrayオブジェクトで、UIBezierPathオブジェクトを格納します。なお、exclusionPathsに設定する非表示領域は、NSTextContainerの座標系を元にします。
[ソースコード41] 非表示領域の設定とテキストの回り込み
UIImageView *imageView =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image"]];
// 画像の表示位置
CGRect imageRect = CGRectMake(100, 100,
imageView.image.size.width,
imageView.image.size.height);
imageView.frame = imageRect;
[self.textView addSubview:imageView];
// 非表示領域の計算(画像の表示位置をテキストコンテナの座標に変換)
CGRect exclusionRect = CGRectOffset(imageView.frame,
-self.textView.textContainerInset.left,
-self.textView.textContainerInset.top);
// 非表示領域の設定
UIBezierPath *path = [UIBezierPath bezierPathWithRect:exclusionRect];
self.textView.textContainer.exclusionPaths = @[path];
上記の通り、非表示領域を設定してその位置に画像を表示すれば、テキストの回り込みが実現できます。exclusionRectとimageRectは異なることに注意してください。exclusionRectはNSTextContainerの座標系、imageRectはUITextViewの座標系で示されます。
NSTextContainerによる表示領域は、デフォルトでsizeプロパティにより示されるサイズを持った矩形領域となっています。これに対して、より複雑な領域を表示領域として設定するには、NSTextContainerをサブクラス化して以下のメソッドをオーバーライドします。
[ソースコード42] ライン矩形を示すメソッド
- (CGRect)lineFragmentRectForProposedRect:(CGRect)proposedRect
atIndex:(NSUInteger)characterIndex
writingDirection:(NSWritingDirection)baseWritingDirection
remainingRect:(CGRect *)remainingRect;
テキストコンテナが示す表示領域の概要を示します(図17)。
lineFragmentRectForProposedRect...メソッドに渡されるproposedRectは、レイアウトマネージャーが計算した行の表示領域で、実際にテキストを表示すべき領域を返します。また、exclusionPathsによる非表示領域があると、非表示領域で分割された領域がremainingRectとして渡されます。そのため、テキストの分割位置もこのメソッドで調整します。
なお、指定したlineFragmentRectに対して、実際にテキストが表示される領域は、lineFragmentPaddingを除いた内側になります。lineFragmentPaddingはNSTextContainerのプロパティで、デフォルト値として0.5が設定されています。
図17: 表示領域の詳細設定に関するパラメータ


