2

我不知道这个的正确标题是什么,但这就像一个划痕和揭示的东西。

这里是什么样的。我必须重叠 UIImageViews,现在我想要做的是擦除视图的某些部分,其中触摸点将显示后面的图像。它类似于触摸绘图,但它的作用是擦除某些点而不是在其上绘图。

我尝试在网上搜索,但找不到任何东西。

有人有想法吗?

4

2 回答 2

9

github 上有一个很棒的控件,它是 MIT 许可的。也许它会帮助你得到一些想法,

https://github.com/akopanev/iOS-Scratch-n-See

祝你好运!

于 2012-06-20T13:40:28.467 回答
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;

这不是一个非常优雅的实现,但它为您提供了基本思想。您可以随心所欲地使用它。

于 2012-07-14T18:27:03.757 回答