在iOS上模拟屏幕截图闪烁动画

8

我正在寻找一种复制“闪烁”动画的方法,该动画在按home + lock时播放。

有人知道是否可以获得此动画吗?

5个回答

10

在iOS设备上,当您按下主页+锁定键并屏幕闪白时,您会拍摄屏幕截图。您是指这种效果吗?如果是,请尝试以下操作:

添加一个带有白色背景颜色的UIView到您的视图层次结构中,以覆盖整个屏幕。然后,启动一个动画,将此视图的不透明度淡化为零。完成后,从其父视图中删除该视图:

[UIView animateWithDuration: 0.5 
                 animations: ^{
                               whiteView.alpha = 0.0;
                             }
                 completion: ^(BOOL finished) {
                               [whiteView removeFromSuperview];
                             }
];

尝试过这个,但它仍然不能像home+lock功能一样影响整个屏幕。我需要将whiteView置于所有其他视图之上才能使其起作用,但这样我就无法点击按钮等内容。有什么建议吗? - Anders
如果您希望整个屏幕闪烁,将白色视图添加到应用程序的“UIWindow”并相应地设置框架。如果您在动画开始之前的那一刻添加白色视图并按建议在完成时将其删除 - 除了短暂的闪光外,所有按钮都可以一直使用。这会造成问题吗? - Theo

3

这些例子给了我灵感,但没有达到我想要的效果。这是我的尝试,看起来非常接近真实情况。

func mimicScreenShotFlash() {

    let aView = UIView(frame: self.view.frame)
    aView.backgroundColor = UIColor.whiteColor()
    self.view.addSubview(aView)

    UIView.animateWithDuration(1.3, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
        aView.alpha = 0.0
        }, completion: { (done) -> Void in
            aView.removeFromSuperview()
    })
}

3

尝试:

[UIView animateWithDuration:1 animations:^{
    self.view.backgroundColor = [UIColor blackColor];
    for (UIView *view2 in self.view.subviews) {
        view2.backgroundColor = [UIColor blackColor];
    }
}];
[UIView animateWithDuration:1 animations:^{
    self.view.backgroundColor = [UIColor whiteColor];
    for (UIView *view2 in self.view.subviews) {
        view2.backgroundColor = [UIColor whiteColor];
    }
}];

您可能希望闪烁所有视图(可以通过for循环找到),以增强动画效果。 - Andrew
太好了!这是我能想到的针对这种情况的最佳解决方案。 - Andrew
@AbdullahShafique 我相信它是有效的,也许是我做错了什么。我尝试在一个没有子视图的UIView上进行测试(只是想测试代码,所以我省略了for循环)。self.view.backgroundColor是白色的。但是没有闪烁效果。 - Unheilig
非常感谢你,Abdullah。这个代码在某种程度上可以正常工作。我想把这个动画放在我的MKMapkit的顶部。但是现在,由于没有显示任何背景,所以这段代码没有效果。希望你能理解我的意思。 - Anders
我不明白这段代码的作用。你同时启动了两个动画,它们具有相同的持续时间,用于将同一属性(背景颜色)动画到不同的目标值。在我看来,这似乎是未定义的行为。此外,最终你得到的状态与开始时不同 - 所有视图的背景颜色都变成了黑色或白色,无论它们在动画开始前的背景颜色是什么。 - Theo

2

我发现了一种非常简单的方法来精确模仿苹果使用的屏幕截图闪光效果。我希望每个人都至少尝试一次。

UIView * flashView = [[UIView alloc] initWithFrame:self.view.frame];
flashView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:flashView];

[UIView animateWithDuration:1 delay:0.3 options:0 animations:^{
      flashView.alpha = 0;
    } completion:^(BOOL finished)
     {
        [flashView removeFromSuperview]; 
     }];
}

如果我需要连续循环执行这个操作,或者重复10次产生同样的效果怎么办? - Sandeep Singh

0

当前解决方案存在两个问题:

  1. 将视图放在其他视图上可能会(根据我使用UICollectionView和其他垃圾的经验)触发自动布局。自动布局是不好的。自动布局会让机器做大量的工作,并且可能会产生除了计算之外的副作用,这些副作用只是为了消耗CPU和电池而没有任何理由。因此,您不希望给它自动布局的理由,例如向一个真正非常关心保持自己良好布局的视图添加子视图。

  2. 您的视图不一定覆盖整个屏幕,因此如果您想闪烁整个屏幕,最好使用UIWindow...这应该可以隔离任何对添加子视图感到敏感的视图控制器

这是我的实现,一个UIView的类别。我包括了在闪烁窗口之前拍摄屏幕截图并将其保存到相机胶卷中的方法。请注意,当添加时,UIWindow似乎想要执行自己的动画,通常会在大约三分之一秒内淡入。可能有更好的方法告诉它不要这样做。

// stupid blocks
typedef void (^QCompletion)(BOOL complete);

@interface UIView (QViewAnimation)
+ (UIImage *)screenshot; // whole screen 
+ (void)flashScreen:(QCompletion)complete;
- (UIImage *)snapshot; // this view only
- (void)takeScreenshotAndFlashScreen;
@end

@implementation UIView (QViewAnimation)

+ (UIImage *)screenshot;
{

    NSArray *windows = [[UIApplication sharedApplication] windows];
    UIWindow *window = nil;
    if (windows.count) {
        window = windows[0];
        return [window snapshot];
    } else {
        NSLog(@"Screenshot failed.");
        return nil;
    }
}

- (UIImage *)snapshot;
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0);
    [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

+ (void)flashScreen:(QCompletion)complete;
{
    UIScreen *screen = [UIScreen mainScreen];
    CGRect bounds = screen.bounds;
    UIWindow * flash = [[UIWindow alloc] initWithFrame:bounds];
    flash.alpha = 1;
    flash.backgroundColor = [UIColor whiteColor];

    [UIView setAnimationsEnabled:NO];
    [flash makeKeyAndVisible];
    [UIView setAnimationsEnabled:YES];

    [UIView animateWithDuration:0.3
                          delay:0
                        options:UIViewAnimationCurveEaseOut
                     animations:^{
            flash.alpha = 0;
        }
                         completion: ^(BOOL finished)
        {
            flash.hidden = YES;
            [flash autorelease];
            if (complete) {
                complete(YES);
            }

        }];
}

- (void)takeScreenshotAndFlashScreen;
{
    UIImage *image = [UIView screenshot];
    [UIView flashScreen:^(BOOL complete){
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0),
                       ^{
            UIImageWriteToSavedPhotosAlbum(image,self,@selector(imageDidFinishSaving:withError:context:),nil);
        });
    }];
}

- (void)imageDidFinishSaving:(UIImage *)image
                   withError:(NSError *)error
                     context:(void *)context;
{
    dispatch_async(dispatch_get_main_queue(),^{
        // send an alert that the image saved
    });
}

@end

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