如何在IOS中实现局部淡入淡出效果?

7

我有两张图片,其中一张在另一张的后面。我想从左上角开始淡出顶部的图片。我应该如何做?

我应该使用渐变蒙版吗?


你使用了两个UIImageView吗?两个CALayer? - rob mayoff
对我来说无所谓,我可以使用任何一个。 - Burak
2个回答

11

下面是一种技术,可以从左上角到右下角淡出CALayer中的任何内容,显示出CALayer下面的内容。

假设我们将要淡出名为self.fadeViewUIImageView的图层。

我们将创建一个CAGradientLayer并将其用作self.fadeView.layer.mask。梯度将从alpha=0(透明)到alpha=1(不透明)使用四个停止位置:0、0、1、1。是的,两个零然后是两个一。当我们要使fadeView不透明时,我们将把停止位置设置为-1、-.5、0、1。这样两个alpha=0的停止位置完全在图层边界外。当我们要使fadeView透明时,我们将把停止位置设置为0、1、1.5、2。这样两个alpha=1的停止位置完全在图层边界外。CAGradientLayer会自动动画化其停止位置的更改,创建一个交叉淡入淡出效果。

以下是代码:

#import "ViewController.h"

@implementation ViewController

@synthesize fadeView = _fadeView;

static NSArray *locations(float a, float b, float c, float d)
{
    return [NSArray arrayWithObjects:
        [NSNumber numberWithFloat:a],
        [NSNumber numberWithFloat:b],
        [NSNumber numberWithFloat:c],
        [NSNumber numberWithFloat:d],
        nil];
}

// In my test project, I put a swipe gesture recognizer on fadeView in my XIB
// with direction = Up and connected it to this action.
- (IBAction)fadeIn
{
    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithDouble:2.0] forKey:kCATransactionAnimationDuration];
    ((CAGradientLayer *)self.fadeView.layer.mask).locations = locations(-1, -.5, 0, 1);
    [CATransaction commit];
}

// In my test project, I put a swipe gesture recognizer on fadeView in my XIB
// with direction = Down and connected it to this action.
- (IBAction)fadeOut
{
    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithDouble:2.0] forKey:kCATransactionAnimationDuration];
    ((CAGradientLayer *)self.fadeView.layer.mask).locations = locations(0, 1, 1.5, 2);
    [CATransaction commit];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    CAGradientLayer *mask = [CAGradientLayer layer];
    mask.frame = self.fadeView.bounds;
    mask.colors = [NSArray arrayWithObjects:
        (__bridge id)[UIColor clearColor].CGColor,
        (__bridge id)[UIColor clearColor].CGColor,
        (__bridge id)[UIColor whiteColor].CGColor,
        (__bridge id)[UIColor whiteColor].CGColor,
        nil];
    mask.startPoint = CGPointZero; // top left corner
    mask.endPoint = CGPointMake(1, 1); // bottom right corner
    self.fadeView.layer.mask = mask;
    [self fadeIn]; // initialize mask.locations
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

谢谢,但我无法让代码工作。你有示例项目吗? - Burak
先生,我也想将动画与 iPad 的翻转或俯仰运动联系起来。我从传感器中获取角度。所以,当我翻转 iPad 时,应该像 http://vimeo.com/32931599 中的那样发生淡入淡出效果。您有什么想法吗? - Burak
1
你可以通过更改 mask.startPointmask.endPoint 来改变淡入淡出的方向。 - rob mayoff
是的,但是例如,如果我将iPad旋转1度,梯度应该改变1度。我可以做到这一点吗? - Burak
谢谢@robmayoff,你真是太棒了。工作得非常好,完美无缺。 - Gurinder Batth

2

定义自己的CALayer子类,为键contents创建自己的actionForKey动画。

@interface CustomLayer: CALayer

@end

@implementation CustomLayer


+ (id<CAAction>)actionForKey:(NSString*)event {

if ([event isEqualToString:@"contents"]) {
    CATransition* basicAnimation = [CATransition animation];
    basicAnimation.type = kCATransitionMoveIn;
    basicAnimation.subtype = kCATransitionFromLeft;
    return basicAnimation;
} else {
    return nil;
}
}

@end

这样做,每当您设置CustomLayer对象的contents属性时,过渡效果都会显示出来:
CustomLayer* layer = [CustomLayer layer];
layer.contents = <FIRST_CGIMAGEREF_HERE>;
...
layer.contents = <SECOND_CGIMAGEREF_HERE>;

通常情况下,您可以将属性赋值包装在事务中:

[CATransaction begin];
    ....
[CATransaction end];

如果你想要更多地控制过渡的持续时间,但无论如何过渡都会被应用。

编辑:

对于您想要的过渡类型,您可以查看GitHub上的此示例。寻找ShutterTransition。它不完全是您要寻找的,但它可能会引导您朝着正确的方向前进。


我认为你的建议是关于过渡的。我需要的是像http://vimeo.com/32931599这样的东西。 - Burak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接