Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 图形上下文有问题_Ios_Uiview_Core Graphics_Cgcontextref - Fatal编程技术网

Ios 图形上下文有问题

Ios 图形上下文有问题,ios,uiview,core-graphics,cgcontextref,Ios,Uiview,Core Graphics,Cgcontextref,我正在开发多终端屏幕应用程序,为此我为终端视图提供了一个自定义的UIView子类。每次我需要一个新的终端屏幕时,我都会准备一个新的视图 此视图类使用CGContextRef绘制文本。我面临的问题是,上下文仅绘制创建的最后一个视图的文本,例如,如果我有3个端子,并且在第一个/第二个端子上绘制,它仍然在第三个端子上绘制 到目前为止,我的代码是: -(void)drawRect:(CGRect)rect{ contxt = UIGraphicsGetCurrentContext(); }

我正在开发多终端屏幕应用程序,为此我为终端视图提供了一个自定义的
UIView
子类。每次我需要一个新的终端屏幕时,我都会准备一个新的视图

此视图类使用
CGContextRef
绘制文本。我面临的问题是,上下文仅绘制创建的最后一个视图的文本,例如,如果我有3个端子,并且在第一个/第二个端子上绘制,它仍然在第三个端子上绘制

到目前为止,我的代码是:

-(void)drawRect:(CGRect)rect{  
    contxt = UIGraphicsGetCurrentContext();
}


-(void)setNeedsDisplayInRect:(CGRect)rect{

    UIGraphicsPushContext(contxt);

    //CGContextSaveGState(contxt);

    CGContextSetTextMatrix(contxt,CGAffineTransformIdentity);
    if (translated) {
        CGContextScaleCTM(contxt, 1, -1);
        translated = NO;
    }
    CGRect rectConvert = CGRectMake(rect.origin.x, rect.origin.y-screenWindowHeight, rect.size.width, rect.size.height);

    CGContextSetFillColorWithColor(contxt, bgColor.CGColor);
    CGContextFillRect(contxt, rectConvert);

    if (!isDeleteChar) {
        CGContextSetFillColorWithColor(contxt, fgColor.CGColor);
        [displayString drawInRect:rectConvert withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentLeft];
    }
    if (ul == EXTENDED_5250_UNDERLINE) {
        CGContextSetFillColorWithColor(contxt, fgColor.CGColor);
        [@"_" drawInRect:rectConvert withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentLeft];
    }

    //CGContextRestoreGState(contxt);
    UIGraphicsPopContext();
}
最后我用自己的方法解决了


[[NSRunLoop currentRunLoop]运行模式:NSDefaultRunLoopMode beforeDate:[NSDate date]]
setNeedsDisplay

之后,首先,您不应该在
-setNeedsDisplayRect:
方法中进行绘图,所有绘图代码都应该在
drawRect:
中。这样,主运行循环可以更好地组织视图的重画

其次,我怀疑用于
CGRect
转换的变量有错误,并且超出了视图边界。您可以通过剪切视图的图形来测试这一前提(将视图的
layer.masksToBounds
设置为
YES

如果是这种情况,可以将它们调整为相对于视图(视图中的所有图形都应相对于其边界,而不是其框架)。绘制视图时,假设画布拉伸视图的
边界
属性,即
(0,0)
处的原点和
的大小(宽度、高度)

现在,还值得讨论传递给
drawRect:
rect
属性实际上是什么,它不能保证是视图的整个边界,因此您不应该假设它是。这是需要重绘的视图部分,但是,通常的做法(对于更简单的视图)是忽略该参数,只重绘整个视图。一旦这变得过于昂贵(或者您需要更优化的图形),您可以考虑对视图进行部分重画


总而言之,如果不查看整个
UIView
子类代码,就很难诊断完整的问题。

实际上,代码是在setNeedsDisplayInRect:而不是drawRect:中编写的,因为当我们按home键时,drawRect方法仅被调用(在ios6中),使用另一个应用程序并返回该应用程序,然后清除内容。就是这样。是的,因为每当您希望系统重新绘制时,都必须对其调用
[view setneeds display]
(在您的情况下,只要影响图形的文本或标志发生更改)。我坚持我的观点,
setNeedsDisplay
(如文档中所述)用于通知系统视图已脏,需要重新绘制,所有绘制都应在
drawRect
中进行。是的,我同意您的观点,但这是问题的唯一原因吗?我如何处理iOS6在返回应用程序时调用drawRect的问题?您可以收听UIApplicationIDBecMeactiveNotification并从那里调用setNeedsDisplay。“并在上下文引用的另一个视图上绘制。”这正是在
drawRect:
之外进行绘图时可能遇到的问题。您试图绕过绘图系统,并依赖于它没有承诺的东西。将图形移动到
drawRect:
。如果需要跟踪旧绘图,请维护自己的位图上下文并将其绘制到其中(然后将其绘制到
drawRect:
中的主上下文中)。但是你不能像使用草稿本一样使用主上下文。这个解决方案是非常失败的。正如@HenriNormak所指出的,您不能在
setNeedsDisplayInRect
中绘制。您在
drawRect:
中获取的上下文在您使用它时并不保证是有效的。通过滥用runloop,您恰好可以侥幸逃脱,但这可能会导致极其令人惊讶的副作用和死锁
drawRect:
是唯一允许您在主上下文中进行绘制的地方。@RobNapier,您完全正确,但是,我需要继续使用前面编写的代码,这就是为什么我必须这样做的原因。