当自动布局调整大小时,如何为 NSWindow 的大小变化设置动画?
How do I animate a NSWindow's size change when it gets resized by Auto Layout?
考虑一个 NSWindow
,它的高度由一组复杂的约束控制,我想在约束导致 window 得到时让 window 的大小调整动画调整大小。
作为一个简单的 示例,我们假设 Window 没有子视图,而不是一组复杂的约束,我们只使用一个直接约束控制 window 的内容视图的高度。
现在,当我更改约束时,window 会隐式调整大小。但是由于我自己没有设置 window 的框架(在复杂的模型中我无法预测新的大小!),我无法使用通常用于动画 window 调整大小的动画功能 window 调整大小。那么,当 Auto Layout 控制调整大小时,如何让调整大小动画化?
这是 Swift 中的示例。要使用它,只需在 Xcode 中创建一个新的普通“Cocoa App”项目,然后在 AppDelegate 中替换以下函数:
func applicationDidFinishLaunching(_ aNotification: Notification) {
let view = self.window.contentView!
// Add a height constraint to the window's view
let heightConstraint = NSLayoutConstraint.init(item: view, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: view.frame.size.height)
view.addConstraint(heightConstraint)
// Resize the window after a brief delay
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// Now change the constraint, which results in the window getting resized instantly.
// But I would like the window's size change animated. How do I accomplish this?
NSAnimationContext.runAnimationGroup(
{ context in
context.duration = 0.5
heightConstraint.constant = heightConstraint.constant + 100
},
completionHandler:nil
)
}
}
有一个约束的代理对象。设置 animator() 的常量,而不是更改约束的常量。它会动画。动画结束后调用 self.layoutSubtreeIfNeeded()
更新约束。
NSAnimationContext.runAnimationGroup({ context in
context.duration = 0.5
context.allowsImplicitAnimation = true
heightConstraint.animator().constant = heightConstraint.constant + 100
}, completionHandler: {
view.layoutSubtreeIfNeeded()
})
考虑一个 NSWindow
,它的高度由一组复杂的约束控制,我想在约束导致 window 得到时让 window 的大小调整动画调整大小。
作为一个简单的 示例,我们假设 Window 没有子视图,而不是一组复杂的约束,我们只使用一个直接约束控制 window 的内容视图的高度。
现在,当我更改约束时,window 会隐式调整大小。但是由于我自己没有设置 window 的框架(在复杂的模型中我无法预测新的大小!),我无法使用通常用于动画 window 调整大小的动画功能 window 调整大小。那么,当 Auto Layout 控制调整大小时,如何让调整大小动画化?
这是 Swift 中的示例。要使用它,只需在 Xcode 中创建一个新的普通“Cocoa App”项目,然后在 AppDelegate 中替换以下函数:
func applicationDidFinishLaunching(_ aNotification: Notification) {
let view = self.window.contentView!
// Add a height constraint to the window's view
let heightConstraint = NSLayoutConstraint.init(item: view, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: view.frame.size.height)
view.addConstraint(heightConstraint)
// Resize the window after a brief delay
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// Now change the constraint, which results in the window getting resized instantly.
// But I would like the window's size change animated. How do I accomplish this?
NSAnimationContext.runAnimationGroup(
{ context in
context.duration = 0.5
heightConstraint.constant = heightConstraint.constant + 100
},
completionHandler:nil
)
}
}
有一个约束的代理对象。设置 animator() 的常量,而不是更改约束的常量。它会动画。动画结束后调用 self.layoutSubtreeIfNeeded()
更新约束。
NSAnimationContext.runAnimationGroup({ context in
context.duration = 0.5
context.allowsImplicitAnimation = true
heightConstraint.animator().constant = heightConstraint.constant + 100
}, completionHandler: {
view.layoutSubtreeIfNeeded()
})