开发者

How to get rid of previous reflection when reflecting a UIImageView (with changing pictures)?

I have managed to use the reflection sample app from apple to create a reflection from a UIImageView.

The problem is that when I change the picture inside the UIImageView, the reflection from the previous displayed picture remains on the screen. The new reflection on the next picture then overlaps the previous reflection.

How do I ensure that the previous reflection is removed when I change to the next picture?

Thank you so much. I hope my question is not too basic.

Here is the code which I have used so far:

// reflection
self.view.autoresizesSubviews = YES;
self.view.userInteractionEnabled = YES;


// create the reflection view
CGRect reflectionRect = currentView.frame;

// the reflection is a fraction of the size of the view being reflected
reflectionRect.size.height = reflectionRect.size.height * kDefaultReflectionFraction;

// and is offset to be at the bottom of the view being reflected
reflectionRect = CGRectOffset(reflectionRect, 0, currentView.frame.size.height);

reflectionView = [[UIImageView alloc] initWithFrame:reflectionRect];

// determine the size of the reflection to create
NSUInteger reflectionHeight = currentView.bounds.size.height * kDefaultReflectionFraction;

// create the reflection image, assign it to the UIImageView and add the image view to the containerView
reflectionView.image = [self reflectedImage:currentView withHeight:reflectionHeight];
reflectionView.alpha = kDefaultReflectionOpacity;
[self.view addSubview:reflectionView];

Then the code below is used to form the reflection:

CGImageRef CreateGradientImage(int pixelsWide, int pixelsHigh)
{
    CGImageRef theCGImage = NULL;

    // gradient is always black-white and the mask must be in the gray colorspace
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

    // create the开发者_运维问答 bitmap context
CGContextRef gradientBitmapContext = CGBitmapContextCreate(nil, pixelsWide, pixelsHigh,
                                                               8, 0, colorSpace, kCGImageAlphaNone);

    // define the start and end grayscale values (with the alpha, even though
    // our bitmap context doesn't support alpha the gradient requires it)
    CGFloat colors[] = {0.0, 1.0, 1.0, 1.0};

    // create the CGGradient and then release the gray color space
    CGGradientRef grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2);
    CGColorSpaceRelease(colorSpace);

    // create the start and end points for the gradient vector (straight down)
    CGPoint gradientStartPoint = CGPointZero;
    CGPoint gradientEndPoint = CGPointMake(0, pixelsHigh);

    // draw the gradient into the gray bitmap context
    CGContextDrawLinearGradient(gradientBitmapContext, grayScaleGradient, gradientStartPoint,
                                gradientEndPoint, kCGGradientDrawsAfterEndLocation);
    CGGradientRelease(grayScaleGradient);

    // convert the context into a CGImageRef and release the context
    theCGImage = CGBitmapContextCreateImage(gradientBitmapContext);
    CGContextRelease(gradientBitmapContext);

    // return the imageref containing the gradient
    return theCGImage;
}

CGContextRef MyCreateBitmapContext(int pixelsWide, int pixelsHigh)
{
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    // create the bitmap context
    CGContextRef bitmapContext = CGBitmapContextCreate (nil, pixelsWide, pixelsHigh, 8,
                                                        0, colorSpace,
                                                        // this will give us an optimal BGRA format for the device:
                                                        (kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
CGColorSpaceRelease(colorSpace);

    return bitmapContext;
}

- (UIImage *)reflectedImage:(UIImageView *)fromImage withHeight:(NSUInteger)height
{
    if (!height) return nil;

    // create a bitmap graphics context the size of the image
    CGContextRef mainViewContentContext = MyCreateBitmapContext(fromImage.bounds.size.width, height);

    // offset the context -
    // This is necessary because, by default, the layer created by a view for caching its content is flipped.
    // But when you actually access the layer content and have it rendered it is inverted.  Since we're only creating
    // a context the size of our reflection view (a fraction of the size of the main view) we have to translate the
    // context the delta in size, and render it.
    //
    CGFloat translateVertical= fromImage.bounds.size.height - height;
    CGContextTranslateCTM(mainViewContentContext, 0, -translateVertical);

    // render the layer into the bitmap context
    CALayer *layer = fromImage.layer;
    [layer renderInContext:mainViewContentContext];

    // create CGImageRef of the main view bitmap content, and then release that bitmap context
    CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext);
    CGContextRelease(mainViewContentContext);

    // create a 2 bit CGImage containing a gradient that will be used for masking the 
    // main view content to create the 'fade' of the reflection.  The CGImageCreateWithMask
    // function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient
    CGImageRef gradientMaskImage = CreateGradientImage(1, height);

    // create an image by masking the bitmap of the mainView content with the gradient view
    // then release the  pre-masked content bitmap and the gradient bitmap
    CGImageRef reflectionImage = CGImageCreateWithMask(mainViewContentBitmapContext, gradientMaskImage);
    CGImageRelease(mainViewContentBitmapContext);
    CGImageRelease(gradientMaskImage);

    // convert the finished reflection image to a UIImage 
    UIImage *theImage = [UIImage imageWithCGImage:reflectionImage];

    // image is retained by the property setting above, so we can release the original
    CGImageRelease(reflectionImage);

    return theImage;
}


If you don't want to use IB, just add

reflectionView.image = nil;

before

reflectedImage.image = [self reflectedImage:...

and don't forget this line

if (currentView.image == nil) reflectedImage.image = nil;

or else you'll end up with an old reflection after the image has disappeared.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜