OSX でのスクロールのパフォーマンスを向上させるために、その使用法をよりよく理解しようとしています。より具体的には、画面の横にある「点滅/ちらつき」を根絶しようとしています。高速にスクロールすると、AppKit は、ビューのオーバードローされていない (準備されていない) 部分、またはビューの誤って準備された部分に遭遇します。バックグラウンドのみ。
私の理解では、preparedContentRect は、スクロールビューのオーバードロー セクション (レスポンシブ スクロールに使用できる領域) を表します。
パート1
preparedContentInRect
の 2 つのサブビュー内にコードを配置しました。それぞれが、スクロール時に documentViews と同じように動作するNSScrollView
フローティング サブビューです。NSScrollView
プログラムのpreparedContentInRect
起動直後に が数回呼び出されます (予想どおり)。次に、準備された領域の最後までスクロールしますが、(予期せずに)準備された領域の端に近づくにつれて、再び呼び出されることはありません。なぜだめですか?ユーザーが UI を操作しなくても (システム アイドル状態) preparedContentInRect
、オーバードロー領域を動的に拡大することはありません。
パート2
preparedContentInRect
(上記のように)必要なときにAppKitの呼び出しに頼ることができなかったので。preparedContentRect
クリップビューからの各通知の後に準備するコードを再編成し、手動でboundsChangeNotification
呼び出しprepareContentInRect
て新しいオーバードロー領域を AppKit に通知しました。
カスタムオーバーライドがAppKitへの手動呼び出しとAppKitからの内部呼び出しを区別できるように、「手動」フラグを含めprepareContentInRect
ました-AppKitがオーバードローを台無しにしないように!!!
var manuallyPrepareContentInRect = false
override func prepareContentInRect(rect: NSRect) {
if manuallyPrepareContentInRect{
println("GRID manual prepareContentInRect call: \(rect)")
manuallyPrepareContentInRect = false
super.prepareContentInRect(rect)
return
}
println("GRID bypass AppKit prepareContentInRect call: \(self.preparedContentRect)")
super.prepareContentInRect(self.preparedContentRect)
}
残念ながら、prepareContentRect
意図した準備四角形を報告していますが、スクロールすると、意図したように四角形が準備されていないようです-5,040幅ではなく3,500ポイント幅の四角形を準備するため、待機中に恐ろしい背景色に遭遇しますビューの残りの部分をレンダリングします。
正しいオーバードローを取得していないビューに関する唯一の「特別な」ことは、canDrawSubviewsIntoLayer
.
オーバードローに関して、上記で何を誤解していprepareContentInRect
ますか? AppKit がそのままの動作をするのはなぜですか?