根据UIImageView 类参考,Apple 说不要继承 UIImageView 。感谢@rob mayoff 指出这一点。
但是,如果您要实现自己的 drawRect,请从您自己的 UIView 子类开始。而且,它在您使用的 drawRect 内addClip
。您可以使用 UIBezierPath 执行此操作,而无需将其转换为 CGPath。
- (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];
}
如果要放大或缩小以填充边界,则需要缩放图形上下文。(您也可以将 aCGAffineTransform
应用于 clippingPath,但这是永久性的,因此您需要先复制 clippingPath。)
- (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 对其进行屏蔽。除测试外,请勿使用以下方法。您需要分别缩放图像层和蒙版以使它们对齐。优点是您可以在不渲染底层图像的情况下更改遮罩。
- (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 方法。删除它以提高效率。