57

レイヤーに裏打ちされた NSView とその兄弟に奇妙な問題があり、回転したスーパービューに接続されている既存のビュー階層に追加すると、それらの一部が正しくレンダリングされません。以下、詳細です。

問題

- NSScrollView (layer can be here)
  - NSClipView (or here)
    - Document View (or even here)
      - Some *rotated* subview
        - { Problematic sublings }

したがって、階層自体はかなり単純で一般的です。いくつかのドキュメントを含むスクロールビュー、ドキュメントのサブビューはいくつかのコンテンツを表します。私の場合、それはグラフィック コンテンツであり、回転できます。回転したビューには、いくつかの追加のサブビュー (さまざまなマーカー、コントロール ポイントなど) を含めることができます。バックエンドに CALayer を使用すると、グラフィックが歪むという奇妙な問題に直面します。 問題の図

カメラ画像は個別にレンダリングされます。これらはこのビュー ツリーの一部ではありません。マーカーとボタンに注意してください。

画像でわかるように、サブビュー (ランダム ボタンのみ) を含むいくつかのテスト ビューがあります。右側のオブジェクトは常に正しくレンダリングされます。私のテストによると、レンダリング間にframeRotation[0, pi/2]があるすべての NSView は問題ありません。左側のオブジェクトはぼやけてレンダリングされています。このアイテムのキャッシュ バッファが小さすぎるようです。frameRotationが範囲内にある場合に発生し[pi/2, pi]ます。

最も奇妙なこと

この問題は「リアルタイム ローテーション」では発生しません。つまり、セットアップ階層のframeRoationを変更するだけで、各サブビューがその場所にある場合、すべてが正常に機能します。ただし、サブリングが既に回転したオブジェクトに追加されると、バグが発生し、このぼやけた外観になります。

私のアプリケーションでは、ユーザーがアイテムをクリックすると特別なサブビューが表示されます。これは、兄弟がスーパービューに追加された瞬間です。

バックエンド レイヤーにはサブビュー用のキャッシュ バッファーがあり、ルート ビューを回転させると、サブビューの一部が間違ったサイズで計算されるようです。

どのように実装され、何を試しましたか

  1. ビューは非常にシンプルで標準的です。階層のルート ビューにプッシュしようとし[view setWantsLayer:YES]ました: スクロール ビュー、クリップ ビュー、ドキュメント ビュー、いずれの場合も結果は同じでした。手作りのレイヤーもレイヤーホストもありません。
  2. コンテンツ ビュー、兄弟、および実際にはビュー ツリー全体 (上記のビューを除く) にはレイヤーがありません。ただし、さまざまなアイテムのレイヤーをオンにしようとしましたが、成功しませんでした。
  3. バックエンドレイヤーを強制的に更新 (setNeedsDisplay) しようとしましたが、うまくいきませんでした
  4. レイヤーを完全に再設定することは機能しているようですが、遅れが生じます。

ソリューション?

実際、それが問題です。誰もそのような問題に直面しましたか? 誰かがレイヤーを強制的にすべてのキャッシュを削除して完全に更新する方法を知っているのでしょうか? これまでのところ、私は2つの解決策しかありません.レイヤーを完全にドロップするか(動作しますが、すべてのアイキャンディーも回転します)、レイヤーの呼び出しをリセットしてsetWantsLayer:NOからsetWantsLayer:YES. こいつはひどい性能だ。

4

1 に答える 1

1

あなたは「setNeedsDisplay」を試したと書いています。メインスレッドからこのメソッドを呼び出していますか? 私のアプリケーションの 1 つで、別のスレッドから setNeedsDisplay を呼び出しても何も起こりませんでした。表示が無効であることを確認したい場合は、次のようにディスパッチを使用します。

dispatch_async(dispatch_get_main_queue(), ^{

       [view setNeedsDisplay:YES];
});

さらに、IB インスペクタを見てください。レイヤーに裏打ちされたビューが、レイヤーに裏打ちされていないビューと混在することを好まない場合があります。「View Effects Inspector」で、ルートレイヤーのすべてのサブビューに対してレイヤーサポートがオンになっていることを確認してください。

(私のプログラムでは、レイヤーのサポートがオフになっていると、NSButtons が消えることがありました)

于 2015-01-19T12:12:13.777 に答える