改变层的Z位置时renderInContext不能正常工作

问题描述 投票:3回答:4

我的应用程序允许用户将UIImageView的正面和背面,然后用户可以捕捉画面。这里是我的代码来捕捉屏幕为UIImage

-(UIImage *)imageWithView:(UIView *)view
{
   UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 2.0f);

// I even tried view.layer.presentationLayer but still not working
[view.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();


return image;

}

因为它是慢,有时我不使用[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES](当视图不可见)绘制在黑色的屏幕截图。

但随着renderInContext问题是,UIImageView ( imageView.layer.zPosition = 0.01;etc )之间改变Z位置。在我的iPhone屏幕这项工作正常,当我分配值z位置,但在捕捉屏幕事实证明是错误的。

是否有反正我可以解决这个问题呢?提前致谢

编辑:这是我试图拍摄前做了截图。我用这个代码,以使一个ImageView的显示在一个又一个的前面。

-(void)bringOneLevelUp:(UIImageView*)imageView
{
//_imgArray is sorted by Z position order (small to big)
    NSUInteger currentObjectIndex = [_imgArray indexOfObject:imageView];


if(currentObjectIndex+1< _imgArray.count){

UIImageView *upperImageView = [_imgArray objectAtIndex:currentObjectIndex+1];


    CGFloat currentZIndex = imageView.layer.zPosition;
    CGFloat upperZIndex= upperImageView.layer.zPosition;

    imageView.layer.zPosition = upperZIndex;
    upperImageView.layer.zPosition = currentZIndex;


// swap position in array 
[_imgArray exchangeObjectAtIndex:currentObjectIndex withObjectAtIndex:currentObjectIndex+1];

}

}

而喜欢我解释这个代码在手机屏幕的前面的结果是正确的。该newImageView是lastImageView面前。但是,当我通过renderInContext获取的截屏。他们不是。

ios objective-c iphone uiimageview calayer
4个回答
0
投票

我有这个问题为好。我想用文字后renderInContext上的图像的顶部绘制()。我将它们添加到窗口时定位自己的看法,而不是使用层设置Z位置解决了这个。

我曾经有过将向上设置其z位置的文本字段:

layer?.zPosition = 1

我删除此代码,而是将我的形象的窗口时,我用:

addSubview(image, positioned: .Below, relativeTo: nil)

这解决了这个问题。


0
投票

我面临着同样的问题,它的一个无赖。

我知道这个问题大约2年前有人问,所以无论如何继承人的答案,如果它可以帮助任何人柜面

因此更改子视图zPosition呈现在应用程序完全正常,但实际上用于创建的屏幕截图影响renderByContext。我不知道为什么,我认为这是一个错误。

因此,为了得到截图正常显示,因为它使得在应用程序中,我们需要通过z位置指定手动调用所有子视图的renderByContext以正确的顺序。

    UIGraphicsBeginImageContext(self.view.frame.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [self renderInContext:ctx];

    UIImage *screenShotImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

-(void) renderInContext:(CGContextRef)ctx {
    CGContextBeginTransparencyLayer(ctx, NULL);
    //self.layers is a desc ordered list of views based on its zPosition
    for(UIView *view in self.layers){ 
        [view.layer renderInContext:ctx];
    }
    CGContextEndTransparencyLayer(ctx);
}

0
投票

雨燕4.2

@RameshVel的答案为我工作将其转换成斯威夫特,也许有人需要这样的:

 UIGraphicsBeginImageContext(drawingCanvas.frame.size)
 self.renderInContext(ct: UIGraphicsGetCurrentContext()!)

 guard let image = UIGraphicsGetImageFromCurrentImageContext() else {return}
 UIGraphicsEndImageContext()

而在renderInContext功能:

 func renderInContext(ct:CGContext){

    ct.beginTransparencyLayer(auxiliaryInfo: nil)

    // descendant ordered list of views based on its z-position
    let orderedLayers = self.view.subviews.sorted(by: {
        $0.layer.zPosition < $1.layer.zPosition
    })

    for l in orderedLayers {
        l.layer.render(in: ct)
    }
    ct.endTransparencyLayer()
}

这也可以用CALayers如果你是绘画和增加层数来完成:

 UIGraphicsBeginImageContext(drawingCanvas.frame.size)
 //Canvas is a custom UIView for drawing
 self.renderInContext(ct: UIGraphicsGetCurrentContext()!, canvas: canvas)

 guard let image = UIGraphicsGetImageFromCurrentImageContext() else {return}
 UIGraphicsEndImageContext()

renderInContext功能:

func renderInContext(ct:CGContext, canvas:CustomCanvas){

    ct.beginTransparencyLayer(auxiliaryInfo: nil)
    let layers:[CALayer] = canvas.layer.sublayers!

    let orderedLayers = layers.sorted(by: {
        $0.zPosition < $1.zPosition
    })

    for v in orderedLayers {
        v.render(in: ct)
    }
    ct.endTransparencyLayer()
}

0
投票

这是苹果的一个恼人的错误,但解决的办法很简单,只需重新整理你快照的子视图(及其子视图(等))递归,根据他们的zPositions的观点,用比较。

只需拨打下面的方法,传递你对直接快照之前将快照视图。

///UIGraphicsGetCurrentContext doesn't obey layer zPositions so have to adjust view heirarchy (integer index) to match zpositions (float values) for all nested subviews.
-(void)recursivelyAdjustHeirarchyOfSubviewsBasedOnZPosition:(UIView *)parentView {

    NSArray *sortedSubviews = [[parentView subviews] sortedArrayUsingComparator:
                           ^NSComparisonResult(UIView *view1, UIView *view2)
                           {
                               float zpos1 = view1.layer.zPosition;
                               float zpos2 = view2.layer.zPosition;
                               return zpos1 > zpos2;
                           }];

    for (UIView *childView in sortedSubviews) {
        [parentView bringSubviewToFront:childView];
        [self recursivelyAdjustHeirarchyOfSubviewsBasedOnZPosition:childView];
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.