在屏幕更新后调用drawViewHierarchyInRect时出现iOS8缩放故障:YES

时间:2014-09-27 01:29:54

标签: ios ios8 screenshot

我正在将一个项目从iOS7转换为iOS8,它使用自定义转换,需要在加载afterScreenUpdates:YES后捕获模态,并且看到整个屏幕缩放一秒并缩小比例。在iOS8上转换为照片时,我也会在部分和Yelp应用程序之间的iOS版Flickr应用程序中看到这种情况。

  UIGraphicsBeginImageContextWithOptions(self.view.frame.size, YES, 22.0); 
  [self.view drawViewHierarchyInRect:self.view.frame afterScreenUpdates:YES];
  UIGraphicsEndImageContext();

添加更大的比例因子有助于更多地强调故障......但我只是在示例中按下按钮来调用它。

编辑这似乎发生在iPhone 6和6上,而不是5上。

scale glitch

Sample project github

6 个答案:

答案 0 :(得分:13)

屏幕更新后你需要画画吗?因为我正在使用:

[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];

它似乎在iOS7和iOS8上运行良好。我想这不是一个定期捕捉图像的好方法(比如每秒多次),但它似乎适用于一次性模糊。

答案 1 :(得分:5)

您必须为6和6 plus提供@ 3x启动图像。 6缩放为750x1334,6和正图像缩放为1242x2208。

答案 2 :(得分:2)

即使它看起来像API中的bug,你也可以调用drawViewHierarchyInRect,将afterScreenUpdates设置为NO,如果你使用这样的cunstruction,可以在屏幕更新后构建快照:

typedef void (^CompletionHandlerWithId)(id result);

-(void)imageContaining:(CGRect)rect afterScreenUpdates:(bool)afterScreenUpdates opaque:(BOOL)opaque completion:(CompletionHandlerWithId)completion
{
    bool success __block;
    UIImage *snapshotImage __block = nil;

    CompletionHandler block = ^{

        // Create the image
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, opaque, [[UIScreen mainScreen] scale]);

        success = [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:NO];

        if (success)
        {
            snapshotImage = UIGraphicsGetImageFromCurrentImageContext();

            CGImageRef imageRef = CGImageCreateWithImageInRect(
                                   [snapshotImage CGImage],
                                   CGRectMake(
                                          snapshotImage.scale*rect.origin.x,
                                          snapshotImage.scale*rect.origin.y,
                                          snapshotImage.scale*rect.size.width,
                                          snapshotImage.scale*rect.size.height));

            // or use the UIImage wherever you like
            snapshotImage = [UIImage imageWithCGImage:imageRef scale:snapshotImage.scale orientation:UIImageOrientationUp];

            CGImageRelease(imageRef);
        }

        UIGraphicsEndImageContext();

        if (completion)
        {
            if (! success)
            {
                NSLog(@"Error: [UIView drawViewHierarchyInRect] failed on %@", self);

                (completion)(nil);
            }
            else
            {
                NSLog(@"Success: [UIView drawViewHierarchyInRect] on %@", self);

                (completion)(snapshotImage);
            }
        }
    };

    if (afterScreenUpdates)

        [CATransaction setCompletionBlock:^{
            (block)();
        }];

    else

        (block)();
}    

答案 3 :(得分:1)

当您在运行iOS7的iPad2上运行时,此错误也存在。

修复:设置afterScreenUpdates:为NO

我的应用程序有一些移动的UIButtons,因此我不允许模糊转换,直到移动停止。据我所知,到目前为止,YES或NO没有区别。

答案 4 :(得分:0)

似乎在iOS9 / XCODE 7版本中修复了

答案 5 :(得分:-1)

我找到了解决这个问题的解决方案。

我将@ 3x启动图像添加到我的项目中。并选择启动屏幕文件到" Main"。 这将使应用程序以原始分辨率运行,在iphone6运行时运行较小的边界,但在调用drawViewHierarchyInRect时不会出现故障。 Like this.

然后,在viewDidLoad时将我的视图缩放到全屏。

- (void)viewDidLoad{ 
       [super viewDidLoad];
       UIScreen *mainScreen = [UIScreen mainScreen];
       CGRect tempFrame=mainScreen.bounds;
       double aspect=tempFrame.size.width/320;
       self.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, aspect, aspect);
}

希望有帮助:)