我正在寻找一种复制“闪烁”动画的方法,该动画在按home + lock时播放。
有人知道是否可以获得此动画吗?
在iOS设备上,当您按下主页+锁定键并屏幕闪白时,您会拍摄屏幕截图。您是指这种效果吗?如果是,请尝试以下操作:
添加一个带有白色背景颜色的UIView
到您的视图层次结构中,以覆盖整个屏幕。然后,启动一个动画,将此视图的不透明度淡化为零。完成后,从其父视图中删除该视图:
[UIView animateWithDuration: 0.5
animations: ^{
whiteView.alpha = 0.0;
}
completion: ^(BOOL finished) {
[whiteView removeFromSuperview];
}
];
这些例子给了我灵感,但没有达到我想要的效果。这是我的尝试,看起来非常接近真实情况。
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()
})
}
尝试:
[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];
}
}];
我发现了一种非常简单的方法来精确模仿苹果使用的屏幕截图闪光效果。我希望每个人都至少尝试一次。
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];
}];
}
当前解决方案存在两个问题:
将视图放在其他视图上可能会(根据我使用UICollectionView和其他垃圾的经验)触发自动布局。自动布局是不好的。自动布局会让机器做大量的工作,并且可能会产生除了计算之外的副作用,这些副作用只是为了消耗CPU和电池而没有任何理由。因此,您不希望给它自动布局的理由,例如向一个真正非常关心保持自己良好布局的视图添加子视图。
您的视图不一定覆盖整个屏幕,因此如果您想闪烁整个屏幕,最好使用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