Cocoa Objective-C macOS 应用程序中的 NSButton 增长-收缩动画
NSButton grow-shrink animation in Cocoa macOS application in Objective-C
我在 Objective-C 中有一个 mac 应用程序。
其中,我希望我的按钮在几秒钟后像成长一样动画。
我在 Cocoa 应用程序中找不到任何内容。
[UIView beginAnimations:nil context:NULL];
CGRect pos=v2.bounds;
pos.size.height=500;
pos.size.width=500;
[UIView setAnimationDuration:1.0];
[UIView setAnimationRepeatCount:15];
[UIView setAnimationRepeatAutoreverses:YES];
v2.bounds=pos;
[UIView commitAnimations];
我在 ios 中使用了上面的代码来增加一个按钮,但是如何在 cocoa mac 应用程序中实现这一点?
所以基本上我想要一个 NSButton 的放大和缩小动画。
在cocoa中您有多种动画方式,您可能需要选择一种适合您的方式。例如,您可以使用 NSAnimationContext
来完成此任务,代码如下:
- (IBAction)buttonPressed:(id)sender {
[self runAnimations:10];
}
- (void)runAnimations:(NSUInteger)repeatCount {
CGFloat oldWidth = self.buttonWidthConstraint.constant;
CGFloat oldHeight = self.buttonHeightConstraint.constant;
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.duration = 1.;
self.buttonWidthConstraint.animator.constant = 500;
self.buttonHeightConstraint.animator.constant = 500;
} completionHandler:^{
//change back to original size
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.duration = 1.;
self.buttonWidthConstraint.animator.constant = oldWidth;
self.buttonHeightConstraint.animator.constant = oldHeight;
} completionHandler:^{
if (repeatCount - 1 > 0) {
[self runAnimations:repeatCount - 1];
}
}];
}];
}
最好为既不直接使用 bounds
操作的约束设置动画。但是,如果您真的需要 - 您可以根据需要采用此代码。
可以在 WWDC 2013, Best Practices for Cocoa Animation 中看到有关您在 OSX 上的所有动画选项的精彩视频,我鼓励您完整地观看它。
以下是 Swift5 中的一些示例。
@IBOutlet weak var burpButton: NSButton!
@IBOutlet weak var rotateButton: NSButton!
@IBOutlet weak var flashButton: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
rotateButton.wantsLayer = true
flashButton.wantsLayer = true
burpButton.wantsLayer = true
flashButton.layer?.cornerRadius = 30
flashButton.layer?.masksToBounds = true
flashButton.layer?.borderWidth = 2
flashButton.layer?.borderColor = NSColor.blue.cgColor
rotateButton.layer?.backgroundColor = NSColor.systemRed.cgColor
flashButton.layer?.backgroundColor = NSColor.systemYellow.cgColor
burpButton.layer?.backgroundColor = NSColor.systemBlue.cgColor
}
@IBAction func rotateButtonPressed(sender: NSButton) {
runRotateAnimations(repeatCount: 10)
}
func runRotateAnimations(repeatCount: Int) {
let rotate = CABasicAnimation(keyPath: "transform.rotation")
rotate.fillMode = CAMediaTimingFillMode.forwards
rotate.fromValue = 0.0
rotate.toValue = CGFloat(Double.pi * -2.0)
rotate.duration = 1
rotate.repeatCount = Float.init(exactly: 1)!
rotateButton.layer?.position = CGPoint.init(x: rotateButton.frame.midX, y: rotateButton.frame.midY)
//Make(sender.frame.midX, sender.frame.midY)
rotateButton.layer?.anchorPoint = CGPoint.init(x: 0.5, y: 0.5)
rotateButton.layer?.add(rotate, forKey: nil)
}
@IBAction func burpButtonPressed(sender: NSButton) {
runBurpAnimations()
}
func runBurpAnimations() {
burpButton.layer?.anchorPoint = CGPoint.init(x: 0.5, y: 0.5)
let burp = CABasicAnimation(keyPath: "transform.scale")
burp.fromValue = 0.0
burp.toValue = 1.50 //CGPoint(x: bigWidth, y: bigHeight)
burp.duration = 0.35
//burp.repeatCount = Float.init(exactly: 1)!
burp.repeatCount = 2
burp.autoreverses = true
//burp.speed = 0.75
burpButton.layer?.position = CGPoint.init(x: burpButton.frame.midX, y: burpButton.frame.midY)
burpButton.layer?.add(burp, forKey: nil)
}
@IBAction func flashButtonPressed(sender: NSButton) {
runFlashAnimations()
}
func runFlashAnimations() {
let flash = CABasicAnimation(keyPath: "opacity")
flash.duration = 0.3
flash.fromValue = 1
flash.toValue = 0.1
flash.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
flash.autoreverses = true
flash.repeatCount = 2
flashButton.layer?.add(flash, forKey: nil)
}
我从@SegaZero 那里得到了一些想法。一些来自 this medium article。虽然这篇文章是关于 iOS,但不难找到适用于 macOS 的可用元素。
我在 Objective-C 中有一个 mac 应用程序。
其中,我希望我的按钮在几秒钟后像成长一样动画。
我在 Cocoa 应用程序中找不到任何内容。
[UIView beginAnimations:nil context:NULL];
CGRect pos=v2.bounds;
pos.size.height=500;
pos.size.width=500;
[UIView setAnimationDuration:1.0];
[UIView setAnimationRepeatCount:15];
[UIView setAnimationRepeatAutoreverses:YES];
v2.bounds=pos;
[UIView commitAnimations];
我在 ios 中使用了上面的代码来增加一个按钮,但是如何在 cocoa mac 应用程序中实现这一点?
所以基本上我想要一个 NSButton 的放大和缩小动画。
在cocoa中您有多种动画方式,您可能需要选择一种适合您的方式。例如,您可以使用 NSAnimationContext
来完成此任务,代码如下:
- (IBAction)buttonPressed:(id)sender {
[self runAnimations:10];
}
- (void)runAnimations:(NSUInteger)repeatCount {
CGFloat oldWidth = self.buttonWidthConstraint.constant;
CGFloat oldHeight = self.buttonHeightConstraint.constant;
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.duration = 1.;
self.buttonWidthConstraint.animator.constant = 500;
self.buttonHeightConstraint.animator.constant = 500;
} completionHandler:^{
//change back to original size
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.duration = 1.;
self.buttonWidthConstraint.animator.constant = oldWidth;
self.buttonHeightConstraint.animator.constant = oldHeight;
} completionHandler:^{
if (repeatCount - 1 > 0) {
[self runAnimations:repeatCount - 1];
}
}];
}];
}
最好为既不直接使用 bounds
操作的约束设置动画。但是,如果您真的需要 - 您可以根据需要采用此代码。
可以在 WWDC 2013, Best Practices for Cocoa Animation 中看到有关您在 OSX 上的所有动画选项的精彩视频,我鼓励您完整地观看它。
以下是 Swift5 中的一些示例。
@IBOutlet weak var burpButton: NSButton!
@IBOutlet weak var rotateButton: NSButton!
@IBOutlet weak var flashButton: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
rotateButton.wantsLayer = true
flashButton.wantsLayer = true
burpButton.wantsLayer = true
flashButton.layer?.cornerRadius = 30
flashButton.layer?.masksToBounds = true
flashButton.layer?.borderWidth = 2
flashButton.layer?.borderColor = NSColor.blue.cgColor
rotateButton.layer?.backgroundColor = NSColor.systemRed.cgColor
flashButton.layer?.backgroundColor = NSColor.systemYellow.cgColor
burpButton.layer?.backgroundColor = NSColor.systemBlue.cgColor
}
@IBAction func rotateButtonPressed(sender: NSButton) {
runRotateAnimations(repeatCount: 10)
}
func runRotateAnimations(repeatCount: Int) {
let rotate = CABasicAnimation(keyPath: "transform.rotation")
rotate.fillMode = CAMediaTimingFillMode.forwards
rotate.fromValue = 0.0
rotate.toValue = CGFloat(Double.pi * -2.0)
rotate.duration = 1
rotate.repeatCount = Float.init(exactly: 1)!
rotateButton.layer?.position = CGPoint.init(x: rotateButton.frame.midX, y: rotateButton.frame.midY)
//Make(sender.frame.midX, sender.frame.midY)
rotateButton.layer?.anchorPoint = CGPoint.init(x: 0.5, y: 0.5)
rotateButton.layer?.add(rotate, forKey: nil)
}
@IBAction func burpButtonPressed(sender: NSButton) {
runBurpAnimations()
}
func runBurpAnimations() {
burpButton.layer?.anchorPoint = CGPoint.init(x: 0.5, y: 0.5)
let burp = CABasicAnimation(keyPath: "transform.scale")
burp.fromValue = 0.0
burp.toValue = 1.50 //CGPoint(x: bigWidth, y: bigHeight)
burp.duration = 0.35
//burp.repeatCount = Float.init(exactly: 1)!
burp.repeatCount = 2
burp.autoreverses = true
//burp.speed = 0.75
burpButton.layer?.position = CGPoint.init(x: burpButton.frame.midX, y: burpButton.frame.midY)
burpButton.layer?.add(burp, forKey: nil)
}
@IBAction func flashButtonPressed(sender: NSButton) {
runFlashAnimations()
}
func runFlashAnimations() {
let flash = CABasicAnimation(keyPath: "opacity")
flash.duration = 0.3
flash.fromValue = 1
flash.toValue = 0.1
flash.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
flash.autoreverses = true
flash.repeatCount = 2
flashButton.layer?.add(flash, forKey: nil)
}
我从@SegaZero 那里得到了一些想法。一些来自 this medium article。虽然这篇文章是关于 iOS,但不难找到适用于 macOS 的可用元素。