2013-04-22 16 views
8

をアニメーション化する際に影をちらつきここで別のNSWindow質問があります...私はこの方法で作成された透明ボーダレス窓、...NSWindowの - ボーダレス、透明な窓 - 窓の高さ

- (id)initWithView:(NSView *)view anchorPoint:(NSPoint)anchorPoint position:(NSPoint)position distance:(CGFloat)distance { 
    if (!view) { 
    return nil; 
    } 

    NSSize size = view.intrinsicContentSize; 
    NSRect contentRect = NSMakeRect(0, 0, size.width, size.height); 

    self = [super initWithContentRect:contentRect 
          styleMask:NSBorderlessWindowMask 
          backing:NSBackingStoreBuffered 
           defer:NO]; 

    if (!self) { 
    return nil; 
    } 

    _windowView = view; 
    _anchorPoint = anchorPoint; 
    _position = position; 
    _distance = distance; 

    [self setContentView:_windowView]; 

    [self setExcludedFromWindowsMenu:YES]; 
    [self setMovableByWindowBackground:NO]; 

    [self setOpaque:NO]; 
    [self setBackgroundColor:[NSColor clearColor]]; 

    [self setHasShadow:YES]; 
    [self useOptimizedDrawing:YES]; 

    [self setReleasedWhenClosed:NO]; 

    [self setFrame:[self windowRectWithSize:contentRect.size] display:YES]; 

    [self setAnchorAttribute:NSLayoutAttributeTop forOrientation:NSLayoutConstraintOrientationVertical]; 
    [self setAnchorAttribute:NSLayoutAttributeCenterX forOrientation:NSLayoutConstraintOrientationHorizontal]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(viewFrameDidChange:) 
               name:NSViewFrameDidChangeNotification 
              object:nil]; 

    return self; 
} 

を持っています.. 。そしてviewFrameDidChange:が、これは適切なNSWindow影を持っている唯一の方法です...

- (void)viewFrameDidChange:(NSNotification *)note { 
    if (note.object != self.contentView) { 
    return; 
    } 

    [self display]; 
    [self setHasShadow:NO]; 
    [self setHasShadow:YES]; 
} 

...と定義されます。それはウィンドウ全体の周りではありません - - 言い換えれば、いつでもウィンドウサイズの変更、私はそうでない場合は、ウィンドウの影が不自由さdisplaysetHasShadow:NOsetHasShadow:YESを呼び出す必要がありますなど、ウィンドウの一部だけ

私が開始するまで、この作業を行いますアニメーションの高さ。高さがアニメーション化されている場合、シャドウは正しく再計算されて表示されますが、全体のウィンドウ&のシャドウはちらつきますが、かなり醜いです。

なぜ影がちらついているのでしょうか? displaysetHasShadow:NO/YES[self invalidateShadow]に置き換えようとしましたが、全く動作せず、影が間違った方法で表示されます。

ちらつきを避けるために、ボーダーレス/トランスペアレントウィンドウでシャドーでウィンドウの高さをアニメートする方法はありますか?

ここでは、ちらつきの影の映像があります。 http://d.pr/v/lbkQ

+1

私はこれを検索しましたが、これは非常に難しい質問です。 Appleとのデベロッパーテクニカルサポートを行うことをお勧めします(デベロッパーとして年間2人無料)。私はそこの誰かがあなたのためにこの問題を解決できると確信しています。 – sangony

+1

制御された環境で問題を再現しようとしましたが、失敗しました。同じタイプの透明なウィンドウ(透明なクリップ付き)では、ちらつきのない良いシャドウが得られます。私はサイズ変更の通知を無効にすることさえしました。 [コードはこちらです](https://dl.dropboxusercontent.com/u/20258059/WindowShadows.zip)。おそらく、それは影自体とは関係がありませんが、最終的には影に影響を与える内面図を再描画します。ウィンドウのサイズ変更は、ウィンドウをクリックすることによって行われます。 – aLevelOfIndirection

答えて

2

シャドウの計算と描画は、非常にリソースを消費する操作です。したがって、フレームが変更されるたびに影を無効にして再計算することはお勧めしません。さらに、NSWindowDelegateには–windowDidResize:メソッドがあります。なぜ、observerを使うのですか?

  1. どのようにウィンドウのサイズを変更しますか?ウィンドウのスタイルマスクにNSResizableWindowMaskを追加すると、そのトリックが実行されますか?あなたはそれを試してみるべきです。

  2. もう1つの提案 - ウィンドウのコンテンツがウィンドウと共に正しくサイズ変更されていることを確認します。ウィンドウを透明に設定します。しかし、ウィンドウ内にコンテンツがない場合、影は表示されません。既存のウィンドウのcontentViewを置き換えるのではなく、サブビューとしてビューを追加することもできます。

私のプロジェクトにはほとんど同じ設定があり、ウィンドウのサイズを変更するとウィンドウの影が正しく表示されます。

P.S.推奨事項:オブジェクトの初期化メソッドで「自己」に頼らないでください。まだ完全に使用準備が整っていない可能性があります。最小値で初期化するには、コントローラーの作成者の後にウィンドウを調整します(たとえば、setFrame:ディスプレイが正しいサイズで期待通りに動作するかどうかを確認することはできません)。あなたが持っている不具合もこれに関連するかもしれません。

+0

もう一つのアイデアが私の心に入ってきました...あなたは、この影の無効化がなければ、窓の影が不自由だと言いました。たぶん、ウィンドウのこの領域に半透明のコンテンツがありますか? – UJey

+1

'[window display]を呼び出すとタイミングが問題になる可能性があります。 [window invalidateShadow]; '-windowDidResize:'で、問題なく動作します。しかし、私が 'contentView'フレームの変更を聞いて、そこの2つのメソッドを呼び出すと、地獄のように点滅していました。 – robertvojta

+0

UJey - 言い換えれば、問題は解決されています。 – robertvojta

2

アニメーションの開始時にシャドウをオフにしてから、やり直したほうがよい場合があります。アニメーション中はこの設定を切り替えないでください。私はこれを他の窓でも見たと思った。

+0

ありがとうございますが、これは私が使いたい最後の方法です。ファンタスティックを見て、問題なくサイズを変更しています。または彼らはカスタムシャドウを持っています... – robertvojta