0

選択を識別するために、サブクラス化された NSView の外側にフォーカス リングを作成したいと考えていました。私の参照はここから来ています: Link

参照に従って、-drawRectメソッドを次のように上書きしました。

@property (nonatomic) BOOL shouldDisplayFocus;
...

- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
if (_shouldDisplayFocus)
{
    [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]];
}

[super drawRect:dirtyRect];
[[NSColor blackColor] set];
NSRectFill(dirtyRect);

if (_shouldDisplayFocus)
{
    NSSetFocusRingStyle(NSFocusRingTypeExterior);
    NSBezierPath *path = [NSBezierPath bezierPathWithRect:NSInsetRect([self bounds], -1.0, -1.0)];
    [[NSColor blackColor] set];
    [path stroke];

    [NSGraphicsContext restoreGraphicsState];
}
}

そしてその-mouseDown:メソッドも上書きされました:

- (void)mouseDown:(NSEvent *)theEvent
{
[super mouseDown:theEvent];
if (_delegate && [_delegate respondsToSelector:@selector(mouseDownAtView:withEvent:)])
{
    [_delegate mouseDownAtView:self withEvent:theEvent];
}
}

ビューがクリックされた後、そのデリゲートはフォーカスリングを設定/設定解除し、-drawRect:再度呼び出されます。




それは機能し、ビューの外側にあるフォーカス リングを正しく生成しました。しかし、すぐに 1 つの問題が発生しました。

サブクラス化されたビュー内に画像ビューがありました。画像ビューの四角形は NSLayoutConstraint オブジェクトで自動レイアウトされたので、値を調整するために 4 つの NSLayoutConstraint アウトレットを作成します。レイアウトの制約を頻繁に変更することはありません。実は、画像サイズは変わらないので、設定しませんでした。

サブクラス化されたビューがクリックされなかった場合の状況は次のとおりです (問題ないように見えました)。

次に、画像をクリックします(フォーカスリングが生成されますが...):

そして、ウィンドウのサイズを変更しようとしましたが、さらに悲しいことに「おかしくなりました」:

なぜ問題なのか、それを解決する方法がわかりませんでした。誰でもそれを手伝ってもらえますか?ここにサンプル コードをアップロードしました:ダウンロード


この質問に誰も答えないのはとても悲しいことです。

-addSubview:メソッドによってこのビューにサブビューを追加すると、サブビューも正しくレイアウトされないことに気付きました-setFrame

4

1 に答える 1

2

本当に遅い答えですが、とにかくここにあります。ブロック[NSGraphicsContext saveGraphicsState]の開始時に呼び出しませんでした。if (_shouldDisplayFocus) {

グラフィックス状態をスタックからポップするために呼び出します[NSGraphicsContext restoreGraphicsState]が、スタックには何も入れません。Cocoa はグラフィックス状態スタックを使用してすべてを描画しているため、画像の位置と関係のある未知の状態をポップオフしています。フォーカス リングのスタイルを追加し、フォーカス リングのスタイルを削除できるようにする場合は、最初にグラフィックスの状態を保存し、フォーカス リングのスタイルを任意に設定してから、グラフィックスの状態を元に戻す必要があります。

于 2016-07-12T03:50:33.710 に答える