为什么UIScrollView的自定义子视图完全重绘,不仅部分重绘,如何更改?

时间:2013-05-27 16:08:36

标签: iphone ios uiscrollview drawrect waveform

我有一个UIScrollView及其子节点,一个自定义视图,其宽度比UIScrollView宽。在某些时候,我放大自定义视图(仅宽度),我只想重绘它被放大的部分。这就是整个问题。其余的只是我试图实现这一目标的细节。

经过一番搜索后,我找到了属性UIView.contentMode,这应该是出于此目的。我玩过它(例如将其设置为UIViewContentModeLeft),但我无法从中获得任何效果。我之前没有使用过这个属性,所以我可能没有正确使用它。

我的问题是自定义视图的drawRect:(CGRect)rect方法总是被调用自定义视图的完整大小,而不仅仅是用于放大它的矩形。这会导致性能问题,因为自定义视图增长越多,绘制周期越长越长。

我在更新代码中的操作:

dispatch_async( dispatch_get_main_queue(), ^{
    uiScrollView.contentSize = ...; // increase width of contentSize
    customView.frame = ...; // increase width of customView accordingly

    CGRect visibleRect = [uiScrollView convertRect:uiScrollView.bounds toView:customView];

    printf("setNeedsDisplayInRect: %s\n", NSStringFromCGRect(visibleRect).UTF8String);

    [customView setNeedsDisplayInRect:visibleRect];
});

但是,我在上面指定的rect没有到达customView中的drawRect:方法,在那里我也像这样记录了rect:

- (void) drawRect:(CGRect)rect {
    printf("drawRect: %s\n", NSStringFromCGRect(rect).UTF8String);

    // drawing code here
    // ...
}

代表性的原始输出:

...
setNeedsDisplayInRect: {{426, 0}, {320, 192}}
setNeedsDisplayInRect: {{427, 0}, {320, 192}}
setNeedsDisplayInRect: {{427, 0}, {320, 192}}
setNeedsDisplayInRect: {{427, 0}, {320, 192}}
drawRect: {{0, 0}, {587, 192}}

背景: 我正在尝试创建滚动波形视图。录制时,应显示最新录制的波形。我可以通过简单的圆形缓冲区和自定义视图来实现这一点,但是在录制之后,波形(轨道)也应该显示,并且用户应该能够使用标准手势滚动,所以我还想使用UIScrollView +记录时的customView UI结构以及在两种操作模式之间的UI结构中保持一致。

更新

我刚刚尝试重新绘制customView的可见部分,而不是放大它的部分。但是,这并不会改变整体问题。我同时尝试使用自定义视图放大的矩形,在这种情况下,这是一个1坐标单位宽的矩形,但是具有完全相同的问题:drawRect:仍然使用自定义视图的完整大小调用重新绘制。

这也导致了一个问题:我的自定义视图的最大部分通常是不可见的,因为它滚出显示的区域。为什么iOS告诉我的自定义视图重绘这个不可见的区域?

1 个答案:

答案 0 :(得分:1)

我认为原因是在iOS中调用-setNeedsDisplayInRect:将始终标记整个视图以进行更新。请参阅类似问题here和此Technical Note

解决方案可能是在多个子视图中拆分波形视图,并仅为内容更改的人调用setNeedsDisplay