2

オーディオを録音し、画面に(他のいくつかの要素とともに)波形を描画するアプリケーションがあります。録音中、のcontainerViewに波形を描きたいのですがNSScrollView。containerViewは、新しいオーディオ情報に対応するために拡張を続け、最後までスクロールし続けます。この動作は、GarageBandのスクロールビューが新しい情報を記録するときの動作とまったく同じです。

私はこれを達成する方法を理解しましたが、私のシステムdrawRect:はスクロールを行うときに不必要な数の呼び出しを使用しているようです。これを行う最も効率的な方法は何ですか(contentViewサイズを更新し、展開された領域に新しいコンテンツを描画し、スクロールして端が表示されるようにしますか?どういうわけか、containerViewの幅が大きくなると、各スクロールでdrawRectを5回呼び出すことになります- scrollViewよりも賢明

スクローラーのドキュメントビューが設定されます:

[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がscrollViewよりも小さい場合:

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}}
4

2 に答える 2

1

この種のリアルタイムアプリケーションでは、drawRect:メソッドをオーバーロードするUIViewに描画する代わりに、レイヤーの使用を検討する必要があります。

たぶん、CoreGraphics関数を使用して新しい波形をビットマップに描画し(ディスプレイに書き込まないため、非常に高速です)、新しいCALayerを作成し、その中に画像を配置して、の終了座標に配置することができます。コンテナビュー。

context = CGBitmapContextCreate(etc...);
// draw your graphic (waveform) into the context
CALayer *newlayer = [CALayer layer];
newlayer.contents = CGBitmapContextCreateImage (context);
newlayer.position = CGPointMake(...at the end of container...);
[container.layer addSublayer: newlayer];

コンテナビューのレイヤーには、描画した波形ブロックと同じ数のサブレイヤーがあります。

レイヤーは非常に高速で、既に描画されているウェーブは変更されないため、ビットマップとしてすばやくレンダリングされ、うまくスクロールします。

于 2012-08-07T22:47:46.367 に答える
0

initでは、[self setwantslayer:YES]を呼び出すことができます。このようにして、nsコントロールは自動的にCALayerを追加し、chacheを使用して描画呼び出しを処理します。

于 2013-11-23T23:57:55.443 に答える