ios UIGraphicsGetCurrentContext 似乎返回 nil

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12424690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:07:24  来源:igfitidea点击:

UIGraphicsGetCurrentContext seems to return nil

iospdf

提问by Christian A. Str?mmen

I'm trying to convert individual PDF pages into PNGs here, and it's worked perfectly until UIGraphicsGetCurrentContext suddenly started returning nil.

我正在尝试将单个 PDF 页面转换为 PNG 文件,并且一直运行良好,直到 UIGraphicsGetCurrentContext 突然开始返回 nil。

I'm trying to retrace my steps here, but I'm not quite sure that I know at which point this happened. My frame is not 0, which I see might create this problem, but other than that everything "looks" correct.

我试图在这里追溯我的步骤,但我不太确定我知道这是在什么时候发生的。我的框架不是 0,我认为这可能会造成这个问题,但除此之外,一切“看起来”都是正确的。

Here's the beginning of my code.

这是我的代码的开头。

_pdf = CGPDFDocumentCreateWithURL((__bridge CFURLRef)_pdfFileUrl);
CGPDFPageRef myPageRef = CGPDFDocumentGetPage(_pdf, pageNumber);
CGRect aRect = CGPDFPageGetBoxRect(myPageRef, kCGPDFCropBox);
CGRect bRect = CGRectMake(0, 0, height / (aRect.size.height / aRect.size.width), height);
UIGraphicsBeginImageContext(bRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);

Anybody have any idea what else might be causing the nil context?

任何人都知道还有什么可能导致 nil 上下文?

采纳答案by ETech

Indeed, it is possible to have CGContextRef object reusable after it has been set in drawRect method. The point is - you need to push the Context to the stack before using it from anywhere. Otherwise, current context will be 0x0
1. Add

实际上,在 drawRect 方法中设置 CGContextRef 对象后,可以重用它。关键是 - 在从任何地方使用它之前,您需要将 Context 推送到堆栈。否则,当前上下文将为 0x0
1。添加

@interface RenderView : UIView {
    CGContextRef visualContext;
    BOOL renderFirst;
}


2. In your @implementation first set renderFirst to TRUE before view has appeared on the screen, then:


2. 在你的@implementation 中,在视图出现在屏幕上之前,首先将 renderFirst 设置为 TRUE,然后:

-(void) drawRect:(CGRect) rect {
  if (renderFirst) {
      visualContext = UIGraphicsGetCurrentContext();
      renderFirst = FALSE;
  }
}


3. Rendering Something to the context after the context was set.


3. 设置上下文后将某些内容渲染到上下文中。

-(void) renderSomethingToRect:(CGRect) rect {
   UIGraphicsPushContext(visualContext);
   // For instance
   UIGraphicsPushContext(visualContext);
   CGContextSetRGBFillColor(visualContext, 1.0, 1.0, 1.0, 1.0);
   CGContextFillRect(visualContext, rect);
}


Here is an example exactly matching the thread case:


这是一个与线程案例完全匹配的示例:

- (void) drawImage: (CGImageRef) img inRect: (CGRect) aRect {
    UIGraphicsBeginImageContextWithOptions(aRect.size, NO, 0.0);
    visualContext = UIGraphicsGetCurrentContext();
    CGContextConcatCTM(visualContext, CGAffineTransformMakeTranslation(-aRect.origin.x, -aRect.origin.y));
    CGContextClipToRect(visualContext, aRect);
    CGContextDrawImage(visualContext, aRect, img);
    // this can be used for drawing image on CALayer
    self.layer.contents = (__bridge id) img;
    [CATransaction flush];
    UIGraphicsEndImageContext();
}


And Drawing image from context that was taken before in this post:


而从已在这个岗位之前拍摄背景描绘图片:

-(void) drawImageOnContext: (CGImageRef) someIm onPosition: (CGPoint) aPos {
    UIGraphicsPushContext(visualContext);
    CGContextDrawImage(visualContext, CGRectMake(aPos.x,
                    aPos.y, someIm.size.width,
                    someIm.size.height), someIm.CGImage);
}

Do not call UIGraphicsPopContext() function until you need the context to render your objects.
It seems that CGContextRef is being removed from the top of the graphic stack automatically when the calling method finishes.
Anyway, this example seems to be a kind of Hack - not planned and proposed by Apple. The solution is very unstable and works only with direct method messages calls inside only one UIView that is on the top of the screen. In case of "performselection" calls, Context does not render any results to the screen. So, I suggest to use CALayer as a rendering to the screen target instead of direct graphic context usage.
Hope it helps.

在需要上下文来呈现对象之前,不要调用 UIGraphicsPopContext() 函数。
当调用方法完成时,似乎 CGContextRef 会自动从图形堆栈的顶部删除。
无论如何,这个例子似乎是一种Hack——不是Apple计划和提出的。该解决方案非常不稳定,仅适用于屏幕顶部的一个 UIView 内的直接方法消息调用。在“执行选择”调用的情况下,上下文不会在屏幕上呈现任何结果。因此,我建议使用 CALayer 作为屏幕目标的渲染,而不是直接使用图形上下文。
希望能帮助到你。

回答by Matt

It doesn't have to be called from "drawRect". you can also call it after "UIGraphicsBeginImageContext(bRect.size);"

它不必从“drawRect”调用。你也可以在“UIGraphicsBeginImageContext(bRect.size);”之后调用它

Check in following line

检查以下行

UIGraphicsBeginImageContext(bRect.size);

if bRect.size is not 0,0

如果 bRect.size 不是 0,0

In my case, this was the reason why the returned context on the following line was null.

就我而言,这就是为什么下一行返回的上下文为空的原因。

回答by docksteaderluke

Are you calling UIGraphicsGetCurrentContext() inside of the drawRect method? As far as I know, it can only be called within drawRect, otherwise it will just return nil.

你在 drawRect 方法中调用 UIGraphicsGetCurrentContext() 吗?据我所知,它只能在 drawRect 内调用,否则它只会返回 nil。