AppleはUIImageView class referenceに従って、UIImageViewをサブクラス化しないと言っています。これを指摘してくれてありがとうございます。
ただし、独自のdrawRectを実装する場合は、独自のUIViewサブクラスを使用してください。そしてdrawRectの中にはaddClip
を使用しています。これをCGPathに変換せずにUIBezierPathで行うことができます。
- (void)drawRect:(CGRect)rect
{
// This assumes the clippingPath and image may be drawn in the current coordinate space.
[[self clippingPath] addClip];
[[self image] drawAtPoint:CGPointZero];
}
境界を埋めるためにスケールを拡大または縮小したい場合は、グラフィックスコンテキストを拡大縮小する必要があります。 (あなたが最初clippingPathをコピーする必要があると思いますので、またclippingPathへCGAffineTransform
を適用することができ、それは永久的である。)
- (void)drawRect:(CGRect)rect
{
// This assumes the clippingPath and image are in the same coordinate space, and scales both to fill the view bounds.
if ([self image])
{
CGSize imageSize = [[self image] size];
CGRect bounds = [self bounds];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM(context, bounds.size.width/imageSize.width, bounds.size.height/imageSize.height);
[[self clippingPath] addClip];
[[self image] drawAtPoint:CGPointZero];
}
}
これは、各軸に個別に画像を拡大縮小します。アスペクト比を維持したい場合は、スケーリング全体を調整し、それを中央になるように変換するか、そうでなければ整列させる必要があります。
最終的には、パスが大きく描画された場合、これはすべて比較的遅いです。おそらく、CALayerに画像を保存する方が速く、パスが含まれているCAShapeLayerであるmaskであることがわかります。 のテスト以外の以下の方法は使用しないでください。イメージレイヤーとマスクを別々にスケーリングして整列させる必要があります。メリットは、下にあるイメージがレンダリングされることなくマスクを変更できることです。
- (void) setImage:(UIImage *)image;
{
// This method should also store the image for later retrieval.
// Putting an image directly into a CALayer will stretch the image to fill the layer.
[[self layer] setContents:(id) [image CGImage]];
}
- (void) setClippingPath:(UIBezierPath *)clippingPath;
{
// This method should also store the clippingPath for later retrieval.
if (![[self layer] mask])
[[self layer] setMask:[CAShapeLayer layer]];
[(CAShapeLayer*) [[self layer] mask] setPath:[clippingPath CGPath]];
}
レイヤーマスクを使用してイメージのクリッピングを行うと、drawRectメソッドが不要になります。効率のために取り外します。
クリップする部分をどのように検出していますか?ジェスチャーによる? – Shrawan