8

(10.10 の新機能) NSSplitViewItem を折りたたみ、折りたたみを解除しながら、ウィンドウを移動して全体を「所定の位置に」保持しようとしています。

問題は、アニメーションでけいれんを起こしていることです (ここで見られるように)。

折りたたみを行っているコードは次のとおりです。

func togglePanel(panelID: Int) {

     if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {

          // Toggle the collapsed state
          NSAnimationContext.runAnimationGroup({ context in

               // special case for the left panel
               if panelID == 0 {
                    var windowFrame = self.view.window.frame
                    let panelWidth = splitViewItem.viewController.view.frame.width
                    if splitViewItem.collapsed {
                         windowFrame.origin.x -= panelWidth
                         windowFrame.size.width += panelWidth
                    } else {
                         windowFrame.origin.x += panelWidth
                         windowFrame.size.width -= panelWidth
                    }
                    self.view.window.animator().setFrame(windowFrame, display: true)
               }
               splitViewItem.animator().collapsed = !splitViewItem.collapsed
          }, completionHandler: nil)
     }
}

メイン スレッドで実行されるウィンドウ サイズ変更アニメーションと別のスレッドで実行されるコア アニメーション折りたたみアニメーションが互いに干渉する「ストリームを横断しない」問題 (セッション 213、WWDC'13 から) を認識しています。splitViewItem の折りたたみアニメーションをメイン スレッドに配置することは、間違ったアプローチのように思えます。これを行うには、もっと良い方法があるのではないかとしつこく感じています。

NSSplitViewItems に関するドキュメントが (まだ) どこにも見つからないので、これに関する洞察をいただければ幸いです。

誰かが見たい場合は、ここに GitHub に小さなテスト プロジェクトがあります。

更新上記のプロジェクトは、ソリューションで更新されました。

ありがとう、テオ

4

2 に答える 2

15

この問題は、作成したアニメーションに (1) 分割ビュー アイテム (2) ウィンドウという 2 つの要因があり、それらが同期していないという点で、「ストリームを横断しない」問題に似ています。

'13 Cocoa Animations トークの例では、ウィンドウのフレームのみがアニメーション化されたため、ウィンドウ内のアニメーションが正しくなるように制約が設定されました。

ここで同様のことを試すことができます-ウィンドウのフレームのみをアニメーション化し、分割ビューアイテムはアニメーション化しませんが、アイテムは折りたたみ (非) 縮小に使用される制約を管理するため、アプリはウィンドウ内コンテンツのアニメーション化を正確に制御できません。

窓枠のアニメーション

代わりに、分割ビュー アイテムのアニメーションでアニメーションを完全に駆動し、NSWindow を使用-anchorAttributeForOrientation:してウィンドウのフレームがどのように影響を受けるかを記述できます。

if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {
    let window = self.view.window
    if panelID == 0 {
        // The Trailing edge of the window is "anchored", alternatively it could be the Right edge
        window.setAnchorAttribute(.Trailing, forOrientation:.Horizontal)
    }
    splitViewItem.animator().collapsed = !splitViewItem.collapsed
}

SplitViewItem のアニメーション化

于 2014-07-07T02:40:54.943 に答える
2

Objective C を使用していて、10.11 El Capitan をターゲットにしているすべての人向け。これでうまくいきました。AnchorAttributes を設定する必要はありませんでした。

splitViewItem.collapsed = YES;
于 2015-12-11T16:21:52.667 に答える