Apple говорит, что не следует создавать подкласс UIImageView, в соответствии с ссылкой на класс 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];
}
Если вы хотите увеличить или уменьшить масштаб, чтобы заполнить границы, вам нужно масштабировать графический контекст.(Вы также можете применить CGAffineTransform
к 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, и mask с 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.Снимите его для эффективности.