-1

我正在开发多个终端屏幕应用程序,因为我有一个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] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];之后setNeedsDisplay

4

1 回答 1

2

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

其次,我怀疑您用于CGRect转换的变量有问题并且绘制在视图边界之外。您可以通过剪切视图的绘图来测试这个前提(设置layer.masksToBoundsYES视图)

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

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

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

于 2015-05-05T12:47:09.323 回答