NSCell の再描画の問題
-
11-12-2019 - |
質問
を作成しています NSCell
一部のオブジェクトをビューに直接描画するサブクラス (使用 drawInRect:fromRect:operation:fraction:respectFlipped:hints:
)また、 NSButton
NSView を使用したインスタンス addSubview:
セレクタ。
最初の方法を使用して描画されたオブジェクトはすべて正しく描画されますが、描画に問題があります。 NSButton
正しく。問題は、私の NSButton
インスタンスは正しい場所に描画しますが、何度も描画されます。
しばらくインターネットでこれについて調べたところ、キャッシュの使用を提案する人もいましたが、これが効率的かどうかはわかりません。(for ループを使用してボタンを含む配列を実行すると、大量のデータを表示するため、間違いなくスクロールが遅くなります...)
これはどうやってやりますか?私は間違った木に吠えているのでしょうか?
関連するコードは次のとおりです。
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
NSRect _controlRect = cellFrame;
float _Y = cellFrame.origin.y;
NSRect _accessoryRect = NSMakeRect(_controlRect.size.width - 70.0f, _Y + 9.0f, 50.0f, 23.0f);
_switch = [self _choiceSwitch];
[_switch setFrame:_accessoryRect];
[controlView addSubview:_switch];
}
解決
長い話を短くすると: 友達は友達を許さない addSubview
, 、絵を描きながら。
これは基本的なことであり、 特によく説明されていない 制御インターフェイスの管理の側面ですが、理解しておくことが重要です。
コントローラーにサブビューの「順序」を指示させれば、そのボタンがあからさまにいじられるべきではないことがわかっているので、ぐっすり眠ることができます (カスタム描画ルーチン内でボタンが乱雑に扱われている場合はこの限りではありません)。
この路地では閉じ込められやすい、 だって、ちょっと、私が追加したのは、 NSImageView
私の中で initWithFrame
そしてすべてが大丈夫のようです…でも、それは あるべきやり方ではない, 、おそらく…そして NSControl のサブクラス化を開始するときなど。その理由を理解し始めたときです。
更新しました: カスタム コントロールの設計に関する非常に優れた記事は次のとおりです と 素晴らしいサンプルプロジェクトと同様に 添付 - この種の問題を回避するのに役立つ種類のコード構成を具体化します。例えば..コントローラー クラスでは、各ボタンをどのように独立させ、一意に保ち、他のビューのビジネスから独立させているかがわかります。
for (int butts = 0; butts < 3; butts++) {
NSRect buttFrame = NSMakeRect(0, butts * 10, 69, 10);
ExampleButt *butt = [[ExampleButt alloc]initWithFrame:buttFrame];
[mainView addSubview:butt];
}
他のヒント
"描画" NSButton
セル自体を描画するたびにそのインスタンスをビュー階層に追加するのは、明らかに悪い考えです。代わりに、NSButtonCell を作成し、好みに合わせて構成します。次に、あなたの中で -[NSCell drawInteriorWithFrame:inView:]
セル ivar を使用してその外観を描画します。
クリック可能にしたい場合は、 NSButton
テーブルビューの各セルのインスタンスでは、への呼び出しを避けるようにしてください。 addSubview:
可能であれば。これを行うたびに、コントロール ビューはそのレイアウトを無効にし、すべてを最初から再描画して、場合によってはある種の再帰を行う可能性があります。