5

テキストフィールドとベゼルボタンのあるウィンドウがあります。縁がなく透過的ですが、問題はどのウィンドウでも再現されます。

そのウィンドウのコンテンツ ビューは、IB でウィンドウの背景を描画するカスタム クラスに設定されます。

コードは次のとおりです。

- (void)drawRect:(NSRect)dirtyRect
{
    [NSGraphicsContext saveGraphicsState];

    float cornerRadius = 10;
    NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:self.bounds xRadius:cornerRadius yRadius:cornerRadius];

    [path setClip];

    NSGradient *gradient = [[NSGradient alloc] initWithColorsAndLocations:
                            [NSColor colorWithCalibratedRed:0.96f green:0.96f blue:0.96f alpha:1.00f], 0.0f,
                            [NSColor colorWithCalibratedRed:0.84f green:0.84f blue:0.84f alpha:1.00f], 1.0f,
                            nil];

    [gradient drawInRect:self.bounds angle:270];

    [NSGraphicsContext restoreGraphicsState];
}

オブジェクトが消えたり、テキスト フィールドの背景がウィンドウの背景に変わったりするなど、非常に奇妙なアーティファクトが発生します。

ここに画像の説明を入力 ここに画像の説明を入力

どうしたの?私はそれを分離しようとしましたが、この「グラフィックスコンテキストの状態の保存」のことをいじっていましたが(正しく理解できているかどうかはわかりません)、問題は解決しません。

私は XCode 4.4、SDK は 10.7 (私の OS も同様)、デプロイ ターゲットは 10.6 です。それはおそらく問題ではありませんが、私は過去に似たようなことをしてきましたが、そのような奇妙な問題は一度もありませんでした.

4

3 に答える 3

6

問題は [path setClip] メソッドにあるようです。これをコメントアウトしたところ、テキスト フィールドとボタンが適切に描画されました。

そこで、次の行を置き換えました。

[gradient drawInRect:self.bounds angle:270];

[gradient drawInBezierPath:path angle:270];

すべてが完璧に機能しました。ボタンとテキスト フィールドが期待どおりに表示されました。

NSBezierPath のクラス リファレンスには、次のように記載されています。

クリッピング パスを調整する方法としてこのメ​​ソッドを使用することは避けてください。クリッピング パスが外側のビューによって設定された境界を超えて拡張される可能性があるためです。この方法を使用する場合は、クリッピング パスを変更する前にグラフィックス状態を保存し、完了したらグラフィックス状態を復元してください。

このメソッドは、現在の巻線規則を使用して、レシーバーのクリッピング形状を決定します。このメソッドは、受信者のパスには影響しません。

あなたが見た問題を実際には説明していませんが、他にどのようにグラデーションを描くことができるかを見てみましょう。

于 2012-08-24T16:01:22.490 に答える
0

これを機能させるための 1 つの回避策は、(ウィンドウの -awakeFromNib または -init で) NSImage を self.bounds と同じサイズにしてから、このグラデーションを画像に描画することです (画像の -lockFocus、-unlockFocus を使用します)。window.backgroundColor = [NSColor colorWithPatternImage:image]; を使用して、画像を背景として設定できます。

それはうまくいきますが、私は解決策に満足していません。

上記が機能しない理由はわかりません。そして、私はビューの描画で同様の奇妙な問題を抱えていたので、それがうまくいかなかった本当の理由を知りたい.

于 2012-08-15T19:40:24.220 に答える
0

これは奇妙/迷惑だと思います。レイヤーが互いに干渉している可能性のある場所の問題だと思うかもしれません..しかし、次のことを行わないと解決するのは難しいようです..

これは、あなたが説明したビューですその後-インターフェイスビルダーを介して変更された単純なチェックボックスを使用..

ここに画像の説明を入力

ここに画像の説明を入力

問題のあるコントロールをボックスやビューなどで囲み、インターフェイスビルダーで「コアアニメーション」「setWantsLayer」ボタンをクリックすると、これらのインターフェイス要素がすべての混乱なしに輝きを放つことができることがわかりました。

ここに画像の説明を入力

ばかげた回避策のようなものですが、実際には機能し、簡単です。

PS - この種のトラブルシューティングを行うときは、パラメータをもう少し劇的 (色など) にすることが役立つことがわかりました。特に、何が問題なのかを人々に説明しようとしている場合は..

于 2012-08-27T14:22:43.540 に答える