我不知道这个的正确标题是什么,但这就像一个划痕和揭示的东西。
这里是什么样的。我必须重叠 UIImageViews,现在我想要做的是擦除视图的某些部分,其中触摸点将显示后面的图像。它类似于触摸绘图,但它的作用是擦除某些点而不是在其上绘图。
我尝试在网上搜索,但找不到任何东西。
有人有想法吗?
我不知道这个的正确标题是什么,但这就像一个划痕和揭示的东西。
这里是什么样的。我必须重叠 UIImageViews,现在我想要做的是擦除视图的某些部分,其中触摸点将显示后面的图像。它类似于触摸绘图,但它的作用是擦除某些点而不是在其上绘图。
我尝试在网上搜索,但找不到任何东西。
有人有想法吗?
如果您决定自己滚动,这只是拥有两张图像的过程,一张完全露出划痕,另一张完全隐藏划痕部分。您将这两个图像叠加在一起,根据手势识别器更新并应用蒙版到前面的图像。(您可以首先完全遮盖正面图像,然后在用户划痕时取消遮盖部分,或者像我在这里一样,完全显示正面图像并在用户划痕时遮盖掉部分。)无论如何,当您更新/应用时遮罩到前图像,这将决定后图像将显示多少。
我不是 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;
这不是一个非常优雅的实现,但它为您提供了基本思想。您可以随心所欲地使用它。