图层实时调整大小性能差



我有一个UI,其中NSCollectionViewItem的视图的内容是通过calayer编程绘制的。在调整大小时,我使用CAConstraintLayoutManager来保持子层的布局一致,但是这样做时我的性能非常差。似乎调整窗口的大小,这会导致两个CATextLayer s的大小调整,使它们适合根层的宽度,以及一个CATextLayer的重新定位,使其保持右对齐,导致应用程序花费大部分时间执行CGSScanConvolveAndIntegrateRGB函数(我使用了时间分析器工具)。

最"昂贵"的一层(即使它是唯一显示的一层,也会导致最口吃的一层)是一个包装的多行CATextLayer。我完全不知道如何获得更好的性能(我试过不使用CAConstraintLayoutManager和图层对齐,但我得到了同样的东西)。有人遇到过这个问题吗?有别的办法吗?

PS:我已经子类化了布局管理器,并通过在CATransaction中将YES设置为kCATransactionDisableActions,在- (void)layoutSublayersOfLayer:(CALayer *)layer执行期间禁用了所有动画,但它似乎没有帮助。

编辑:我已经禁用了字体平滑的文本层和性能增加了一点点(非常少),但它花费了一个可怕的时间在_ZL9view_drawP7_CAViewdPK11CVTimeStampb(这是由ATI Radeon驱动程序的线程调用的东西,我想)。

我解决了。种。这对我来说似乎仍然是一个肮脏的hack,但我无法找到如何使setNeedsDisplayInRect工作,所以我最终这样做:

  1. NSWindow委托中:

    - (void) windowWillStartLiveResize: (NSNotification *)通知{[[NSNotificationCenter defaultCenter] postNotificationName:@"beginResize"对象:nil];}

    - (void) windowDidEndLiveResize: (NSNotification *)通知{[[NSNotificationCenter defaultCenter] postNotificationName:@"endResize" object:nil];
    }

  2. 在自定义视图中,这两个通知分别调用-(void)beginResize-(void)endResize选择器。第一个将BOOL变量inLiveResize设置为YES,而第二个将其设置为NO,并使用新的帧大小再次调用setFrameSize。

  3. I overrode (overridden?不是英语为母语的人,抱歉)-(void)setFrameSize:(NSSize)newSize方法如下:

    -(void)setFrameSize:(NSSize)newSize 
    {        
        if (inLiveResize) {
            NSRect scrollFrame = [[[self superview] enclosingScrollView] documentVisibleRect];
            BOOL condition1 = (self.frame.origin.y > (scrollFrame.origin.y - self.frame.size.height));
            BOOL condition2 = (self.frame.origin.y < (scrollFrame.origin.y + scrollFrame.size.height + self.frame.size.height));
            if (condition1 && condition2)
                [super setFrameSize:newSize];
        }
        else {
            [super setFrameSize:newSize]; }}
    

就是这样。这样,只有可视视图与窗口一起调整大小,而其他视图在操作结束时重新绘制。它可以工作,但我不喜欢它有多"脏",我确信有一个更优雅的,内置的(类似的)方法,通过使用setNeedsDisplayInRect方法来做到这一点。我会做更多的研究。

最新更新