Reputation: 3914
I am having a mac app in Objective-C.
In which, I want my button to animate like grow after some seconds.
I couldn't find anything in Cocoa application.
[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];
I used the above code in ios to grow a button but how to make this happen in cocoa mac application?
So basically I want a grown and shrink animation of an NSButton.
Upvotes: 1
Views: 2469
Reputation: 7778
Here are a few examples in 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)
}
I got some ideas from @SegaZero. Some from this medium article. While the article is about iOS, it's not hard to find usable elements for macOS.
Upvotes: -1
Reputation: 3017
In cocoa you have a several ways of animations, you probably need to chose an appropriate for you. For instance you can use NSAnimationContext
for this task with a code like this:
- (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];
}
}];
}];
}
It is much better to animate a constraints neither operating with bounds
directly. But if you really need to - you can adopt this code to whatever you want.
A great video about all the options you have on OSX for animations may be seen in WWDC 2013, Best Practices for Cocoa Animation, I encourage you to watch it completely.
Upvotes: 3