【问题标题】:Unable to animate a Swift custom property with animator() [ OSX ]无法使用 animator() [ OSX ] 为 Swift 自定义属性设置动画
【发布时间】:2016-02-24 12:51:59
【问题描述】:

我正在尝试使用 animator() 在 swift 中为 Objective-C 设置自定义属性的动画。但是当我尝试通过animator 设置属性时,我得到了EXC_BAD_ACCESS 异常。在之前的一个用 Objective-C 编写的应用程序中,我使用了相同的想法,并且成功了。

这是 Swift 中的类:

import Cocoa
import QuartzCore


@IBDesignable
class StopPlayButton: NSView {

    //This is the property that I am trying to animate
    @IBInspectable
    var playButtonShapeInterval:Float = 1.0 {
        didSet{
            self.needsDisplay = true
        }
    }

    @IBInspectable
    var isPressed:Bool = false{
        didSet{
            self.needsDisplay = true
        }
    }
    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)
        StyleKit.drawPlayStopButton(playButtonShapeInterval: CGFloat(self.playButtonShapeInterval), buttonPressed: self.isPressed)
    }

    func toggle(){
        NSAnimationContext.beginGrouping()
        NSAnimationContext.currentContext().duration = 1.0;
        NSAnimationContext.currentContext().timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut);
        if self.playButtonShapeInterval == 0 {
            self.animator().playButtonShapeInterval = 1.0
        }
        else{
            self.animator().playButtonShapeInterval = 0.0//exception happending here...
        }
        NSAnimationContext.endGrouping()
    }
    override static func defaultAnimationForKey(key: String) -> AnyObject?{
        if key == "playButtonShapeInterval" {
            return CABasicAnimation()
        }
        return super.defaultAnimationForKey(key)
    }

}

注意,如果我将属性名称从playButtonShapeInterval 更改为alphaValue,那么alpha 动画就可以了。

下面是上面移植到Objective-C的代码,做我想做的。我不确定有什么不同:

//StopPlayButton.m
#import "StopPlayButton.h"
#import "StyleKit.h"
#import <QuartzCore/QuartzCore.h>

@implementation StopPlayButton

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    NSLog(@"This is the interval: %f", self.playButtonShapeInterval);
    [StyleKit drawPlayStopButtonWithPlayButtonShapeInterval:self.playButtonShapeInterval buttonPressed:self.playButtonPressed];
}

-(void)setPlayButtonShapeInterval:(float)playButtonShapeInterval{
    if(playButtonShapeInterval != _playButtonShapeInterval){
        _playButtonShapeInterval = playButtonShapeInterval;
        [self setNeedsDisplay:YES];
    }
}

-(void)toggle{
    [NSAnimationContext beginGrouping];
    [[NSAnimationContext currentContext] setDuration:0.5];
    [[NSAnimationContext currentContext] setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    if(self.playButtonShapeInterval == 0){
        self.animator.playButtonShapeInterval = 1;
    }
    else{
        self.animator.playButtonShapeInterval = 0;
    }
    [NSAnimationContext endGrouping];
}

+(id)defaultAnimationForKey:(NSString *)key{
    if ([key isEqualToString:@"playButtonShapeInterval"]) {
        return [CABasicAnimation animation];
    }
    return [super defaultAnimationForKey:key];
}

@end

//StopPlayButton.h
#import <Cocoa/Cocoa.h>

@interface StopPlayButton : NSView

@property (nonatomic) BOOL playButtonPressed;
@property (nonatomic) float playButtonShapeInterval;

-(void)toggle;

@end

【问题讨论】:

    标签: swift macos animator


    【解决方案1】:

    我遇到了同样的问题,并通过将自定义属性声明为“动态”来修复它。我相信这是 KVO 要求的。

    dynamic var playButtonShapeInterval:Float = 1.0 {
        didSet{
            self.needsDisplay = true
        }
    }
    

    【讨论】:

    【解决方案2】:

    在 Swift 5 中,你需要这个:

    @objc class YourView: NSClipView {
        @objc dynamic var yourAnimatableProperty = CGFloat(1)
    
        override static func defaultAnimation(forKey key: NSAnimatablePropertyKey) -> Any? {
            if key == "yourAnimatableProperty" {
                return CABasicAnimation()
            }
            return super.defaultAnimation(forKey: key)
        }
    

    ... }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-21
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 2015-04-12
      • 2011-05-06
      • 2013-06-20
      • 1970-01-01
      相关资源
      最近更新 更多