我不知道什么是正确的标题,但这就像是一个划痕和揭示的东西。
这就是它的样子。我必须重叠UIImageViews,现在我要做的是擦除视图的某些部分,其中触摸点是显示背后的图像。它类似于触摸上的绘图,但它的作用是它会删除某些点而不是绘制它。
我尝试在网上搜索但我找不到任何东西。
有人有想法吗?
答案 0 :(得分:9)
github上有一个很棒的控件,它是MIT Licensed。可能会帮助你了解一下,
祝你好运!答案 1 :(得分:1)
如果您决定自己动手,那么这只是一个有两个图像的过程,一个完全显示划痕,另一个完全隐藏划痕部分。您可以将这两个图像直接呈现在彼此之上,根据手势识别器更新并将蒙版应用于前方图像。 (您可以先完全遮住前面的图像,然后在用户划伤时取消遮罩部分,或者像我在这里一样,完全显示前面的图像,并在用户划伤时将部分遮挡掉。)无论如何,当您更新/应用时掩盖前面的图像,这将决定后方图像将显示多少。
我不是Core Graphics的人,但它可能看起来像:
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *backgroundImage = [UIImage imageNamed:@"imgres-1.jpg"];
_foregroundImage = [UIImage imageNamed:@"imgres-2.jpg"];
CGRect frame = CGRectMake((self.view.frame.size.width - _foregroundImage.size.width) / 2.0,
(self.view.frame.size.height - _foregroundImage.size.height) / 2.0,
_foregroundImage.size.width,
_foregroundImage.size.height);
UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:frame];
backgroundImageView.image = backgroundImage;
[self.view addSubview:backgroundImageView];
_foregroundImageMask = [self createBlankMaskForImage:_foregroundImage];
UIImageView *_foregroundImageView = [[UIImageView alloc] initWithFrame:frame];
_foregroundImageView.image = [self maskImage:_foregroundImage withMask:_foregroundImageMask]; // _foregroundImage;
[self.view addSubview:_foregroundImageView];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
_foregroundImageView.userInteractionEnabled = YES;
[_foregroundImageView addGestureRecognizer:pan];
}
- (void)pan:(UIPanGestureRecognizer *)sender
{
static CGPoint lastPoint;
UIImageView *maskedImageView = (UIImageView*)sender.view;
CGPoint location = [sender locationInView:maskedImageView];
if (sender.state == UIGestureRecognizerStateBegan)
{
lastPoint = location;
}
else if (sender.state == UIGestureRecognizerStateChanged)
{
UIGraphicsBeginImageContext(_foregroundImage.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[_foregroundImageMask drawInRect:maskedImageView.bounds];
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, 24.0);
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(context, location.x, location.y);
CGContextStrokePath(context);
_foregroundImageMask = UIGraphicsGetImageFromCurrentImageContext();
maskedImageView.image = [self maskImage:_foregroundImage withMask:_foregroundImageMask];
lastPoint = location;
}
}
- (UIImage *)createBlankMaskForImage:(UIImage *)image
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef context = CGBitmapContextCreate (NULL, image.size.width, image.size.height,
8, 0, colorSpace, kCGImageAlphaNone);
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.0); // don't use alpha
CGContextFillRect(context, CGRectMake(0.0, 0.0, image.size.width, image.size.height));
CGImageRef imageref = CGBitmapContextCreateImage(context);
UIImage *result = [UIImage imageWithCGImage:imageref];
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
CFRelease(imageref);
return result;
}
// the following came from http://mobiledevelopertips.com/cocoa/how-to-mask-an-image.html
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage
{
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
UIImage *result = [UIImage imageWithCGImage:masked];
CGImageRelease(masked);
CGImageRelease(mask);
return result;
}
可能很明显,但这使用了两个ivars:
UIImage *_foregroundImage;
UIImage *_foregroundImageMask;
这不是一个非常优雅的实现,但它为您提供了基本的想法。你可以随意使用它。