我有一個應用程序,它可以在屏幕上記錄音頻並繪製波形(以及其他一些元素)。在錄製時,我想在NSScrollView
的containerView中繪製波形。 containerView不斷擴展以適應新的音頻信息,並保持滾動到最後。這種行爲與GarageBand中的滾動視圖在錄製新信息時的行爲完全相同。NSScrollView使用盡可能少的drawRect函數進行常量滾動(和擴展):儘可能調用
雖然我已經想出瞭如何實現這一點,但我的系統似乎在進行滾動時使用了不必要數量的drawRect:
調用。什麼是最有效的方式來做到這一點(更新contentView的大小,在擴大的區域上繪製新的內容,並滾動,使結束是可見的?不知何故,一旦containerView是更大的寬度,我最終在每個滾動調用drawRect 5次 - 比滾輪的滾動視圖
文檔視圖明智設置:
[self.scrollView setDocumentView:self.containerView];
進一步滾動的方法(從NSTimer
調用):
- (void)scrollFurther {
scrollPoint = ([SSSubdivisionManager manager].lastStartSample + [RemoteIOPlayer remote].diffInFrames)/(zoomLevel * baseZoomLevel);
int scrollWidth = self.scrollView.frame.size.width;
CGRect frame = self.containerView.frame;
if (scrollPoint >= ((scrollPoint + (scrollWidth * 0.5f))/2)) {
if (![SSAudioManager manager].isDoingInputPlayback) {
frame.size.width = scrollPoint + (scrollWidth * 0.5f);
NSLog(@"Setting scroller frame to: %@", NSStringFromRect(frame));
[self.containerView setFrame:frame];
}
NSPoint p = NSMakePoint(scrollPoint - (scrollWidth * 0.5), 0);
NSLog(@"Scrolling to point %@", NSStringFromPoint(p));
[self.containerView scrollPoint:p];
} else {
NSLog(@"Not exapanding frame or scrolling to a point");
[self.containerView setNeedsDisplayInRect:frame];
}
}
而生成的日誌電話:
起初,當containerView比滾動視圖小:
2012-07-29 17:42:43.607 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{0, 0}, {1924, 700}}
2012-07-29 17:42:43.683 MET[4679:503] Setting scroller frame to: {{0, 0}, {1942.3199462890625, 700}}
2012-07-29 17:42:43.684 MET[4679:503] Scrolling to point {580.3199462890625, 0}
2012-07-29 17:42:43.687 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{0, 0}, {1942, 700}}
2012-07-29 17:42:43.757 MET[4679:503] Setting scroller frame to: {{0, 0}, {1957.6800537109375, 700}}
2012-07-29 17:42:43.758 MET[4679:503] Scrolling to point {595.6800537109375, 0}
2012-07-29 17:42:43.760 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{0, 0}, {1957, 700}}
2012-07-29 17:42:43.835 MET[4679:503] Setting scroller frame to: {{0, 0}, {1975.5999755859375, 700}}
2012-07-29 17:42:43.836 MET[4679:503] Scrolling to point {613.5999755859375, 0}
2012-07-29 17:42:43.839 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{0, 0}, {1975, 700}}
2012-07-29 17:42:43.889 MET[4679:503] Setting scroller frame to: {{0, 0}, {1988.4000244140625, 700}}
2012-07-29 17:42:43.890 MET[4679:503] Scrolling to point {626.4000244140625, 0}
2012-07-29 17:42:43.892 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{0, 0}, {1988, 700}}
,然後就失控:
2012-07-29 17:42:43.954 MET[4679:503] Setting scroller frame to: {{0, 0}, {2001.199951171875, 700}}
2012-07-29 17:42:43.956 MET[4679:503] Scrolling to point {639.199951171875, 0}
2012-07-29 17:42:43.960 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1536, 512}, {465.199951171875, 188}}
2012-07-29 17:42:43.961 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1024, 512}, {512, 188}}
2012-07-29 17:42:43.964 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{512, 512}, {512, 188}}
2012-07-29 17:42:43.971 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1536, 0}, {465.199951171875, 512}}
2012-07-29 17:42:43.972 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1024, 0}, {512, 512}}
2012-07-29 17:42:43.977 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{512, 0}, {512, 512}}
2012-07-29 17:42:44.098 MET[4679:503] Setting scroller frame to: {{0, 0}, {2034.47998046875, 700}}
2012-07-29 17:42:44.099 MET[4679:503] Scrolling to point {672.47998046875, 0}
2012-07-29 17:42:44.104 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1536, 512}, {498.47998046875, 188}}
2012-07-29 17:42:44.107 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1024, 512}, {512, 188}}
2012-07-29 17:42:44.112 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{512, 512}, {512, 188}}
2012-07-29 17:42:44.118 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1536, 0}, {498.47998046875, 512}}
2012-07-29 17:42:44.120 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1024, 0}, {512, 512}}
2012-07-29 17:42:44.125 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{512, 0}, {512, 512}}
2012-07-29 17:42:44.154 MET[4679:503] Setting scroller frame to: {{0, 0}, {2047.280029296875, 700}}
2012-07-29 17:42:44.155 MET[4679:503] Scrolling to point {685.280029296875, 0}
2012-07-29 17:42:44.157 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1536, 512}, {511.280029296875, 188}}
2012-07-29 17:42:44.159 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1024, 512}, {512, 188}}
2012-07-29 17:42:44.162 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{512, 512}, {512, 188}}
2012-07-29 17:42:44.168 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1536, 0}, {511.280029296875, 512}}
2012-07-29 17:42:44.172 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{1024, 0}, {512, 512}}
2012-07-29 17:42:44.178 MET[4679:503] -[SSVisualContainer drawRect:] [Line 70] Drawrect: {{512, 0}, {512, 512}}
這並不是真的失去控制。請注意,開頭的每個drawRect調用都會覆蓋整個屏幕區域,而後面的drawRect調用僅覆蓋屏幕區域的一小部分,並且沒有任何重疊。因此,這六個調用實際上比單次調用整個區域的調用更有效**(如果您購買假設{100,100}區域上的drawRect將花費25%的時間作爲{200,200中的drawRect }區域)。 – 2012-08-03 14:08:21
是的,但它每次都重新繪製回0點 - 我只需要在新setFrame調用添加的區域上繪製調用。 – 2012-08-03 18:22:34
我想我正在閱讀日誌的方式,它從來沒有在你提交的第二組中的512左側繪製任何東西。它可能不會被完全優化,但從我所知道的情況來看,那些稍後的drawRect調用只在屏幕的一小部分(前3個是512x188,後面三個是512x512),總而言之,它從不重繪左邊的任何東西屏幕的一部分。 – 2012-08-03 18:57:49