🔥
アニメーションを実装する
UIKitの場合は、UIView.animate(withDuration:animations:completion:)やUIView.perform(_on:options:animations:completion:)などのブロック構文を用いたメソッドでアニメーションを実現していました。
この記事では、AppKitでのアニメーション実装方法の中からいくつかを紹介します。
実装方法
プロパティ1つだけの場合
animator()を利用できます。
例えば、NSSplitViewを使ってPaneのトグル挙動をアニメーション付きで実現する場合なら、以下のように実装します。
@objc func togglePane(sender: Any?) {
paneSplitItem.animator().isCollapsed.toggle()
}
twitterで@dy4_268さんに教えて頂きました!ありがとうございます!
2つ以上のプロパティを同時にアニメーションさせたい場合
NSAnimationContextが利用できます。このオブジェクトはNSGraphicContextのようなAPIでアニメーション操作を行います。以下のように実装します。
-
current
コンテキストの取得 -
allowsImplicitAnimation
をtrue
にセット - アニメーションさせたいプロパティの変更
-
allowsImplicitAnimation
をfalse
にセット
例えば、NSSplitViewを使ってPaneのトグル挙動をアニメーション付きで実現する場合なら、以下のように実装します。
@objc func togglePane(sender: Any?) {
let context = NSAnimationContext.current
context.allowsImplicitAnimation = true
paneSplitItem.isCollapsed.toggle()
context.allowsImplicitAnimation = false
}
何度もこれを書くのは大変なので、CotEditorでは以下のように独自のブロックAPIを実装して使っているようです。
func withAnimation(_ animate: Bool = true, execute block: () -> Void) {
let allowsImplicitAnimation = self.allowsImplicitAnimation
self.allowsImplicitAnimation = animate
block()
self.allowsImplicitAnimation = allowsImplicitAnimation
}
上記のようなAPIを実装しておくと、利用側からは以下のようにシンプルに使えます。
NSAnimationContext.current.withAnimation {
paneSplitItem.isCollapsed.toggle()
}
Discussion