【问题标题】:NSButton grow-shrink animation in Cocoa macOS application in Objective-CObjective-C中Cocoa macOS应用程序中的NSButton增长-收缩动画
【发布时间】:2015-09-21 08:28:57
【问题描述】:

我在 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 的放大和缩小动画。

【问题讨论】:

    标签: objective-c macos animation nsbutton


    【解决方案1】:

    以下是 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 的可用元素并不难。

    【讨论】:

      【解决方案2】:

      在 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 上的所有动画选项的精彩视频,我鼓励您完整观看。

      【讨论】:

      • 感谢您的回复。但是 buttonWidthConstraint 和 buttonHeightConstraint 是什么?我的按钮名称是 btn。我该怎么做?
      • 这些只是在 IB 中按钮上设置的宽度和高度约束作为示例。如果您不使用自动布局(现在这有点奇怪),您可以直接更改按钮边界而不是更改约束,就像在您的代码中一样。但是你应该使用animator代理属性,所以这个属性会被动画化。
      • 我的按钮出口是 btn 但是如果我给 btn.animator.constant,它会给我错误。请帮帮我。
      • 你为什么要输入两次动画师? :) 只需将约束设置替换为btn.animator.bounds = newBounds;
      • 我不后悔,因为我是 mac 开发的新手。你能通过代码让我理解吗?我的按钮名称是 btn,旧的高度、宽度是 130,100。
      猜你喜欢
      • 2012-06-02
      • 1970-01-01
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多