0

我有一个正在开发的简单 Mac 应用程序。我希望能够在 NSButton 上应用变换并使其更大。其大小的两倍。但是我的代码不起作用,它只是将按钮滑到一个角落。有谁知道出了什么问题?

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {

    [numberButton1.animator.layer setAffineTransform:CGAffineTransformMakeScale(4.0, 4.0)];
    numberButton1.layer.anchorPoint = CGPointMake(0.5, 0.5);
    [numberButton1.animator.layer setAffineTransform:CGAffineTransformMakeScale(1.0, 1.0)];

} completionHandler:nil];

更新 1

我尝试了以下,但它没有做任何事情:(

   CGAffineTransform test = CGAffineTransformMakeScale(4.0, 4.0);

   [NSAnimationContext runAnimationGroup:^(NSAnimationContext *ctx) {
        numberButton1.animator.layer.affineTransform = test;
    } completionHandler:^{
        [NSAnimationContext runAnimationGroup:^(NSAnimationContext *ctx) {
            numberButton1.animator.layer.affineTransform = CGAffineTransformIdentity;
        } completionHandler:^{
            NSLog(@"Done...");
        }];
    }];

更新 2

这是我的代码 sudo,希望这会有所帮助:

我的头文件(.h)文件:

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

@interface ViewController : NSViewController {

    IBOutlet NSButton *numberButton1;
}

-(IBAction)demo:(id)sender;

@end

我的实现(.m)文件:

#import "ViewController.h"

@implementation ViewController

-(IBAction)demo:(id)sender {

    CGRect frame = numberButton1.layer.frame;
    CGPoint center = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));
    numberButton1.layer.position = center;
    numberButton1.layer.anchorPoint = CGPointMake(0.5, 0.5);

    [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {

        context.allowsImplicitAnimation = YES;
        [[NSAnimationContext currentContext] setDuration:0.2];
        numberButton1.animator.layer.affineTransform = CGAffineTransformMakeScale(4.0, 4.0);

    } completionHandler:^{

        [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {

            context.allowsImplicitAnimation = YES;
            [[NSAnimationContext currentContext] setDuration:0.2];
            numberButton1.animator.layer.affineTransform = CGAffineTransformIdentity;

        } completionHandler:nil];
    }];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view.

    numberButton1.wantsLayer = YES;
    numberButton1.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
    numberButton1.layer.backgroundColor = [NSColor colorWithRed:(17/255.0) green:(145/255.0) blue:(44/255.0) alpha:1.0].CGColor;
}

- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

    // Update the view, if already loaded.
}

@end

我也没有用于Auto Layout我的 UI 文件。

谢谢,丹。

4

1 回答 1

5

affineTransformon 属性CALayer只是该属性的方便包装器transform。在支持层的视图上,您​​不应该更改它。话虽如此,这是可能的。

您的第一个问题是您无法使用NSAnimation块为图层属性设置动画。您需要显式创建一个CABasicAnimation表示变换动画的对象并将其添加到图层中。编辑:我只记得实际上可以为图层属性设置动画。您需要allowsImplicitAnimation在上下文中启用该属性。此属性的预期目的是让您在不使用动画代理代理的情况下为视图属性设置动画,但副作用是它允许您为隐式图层属性设置动画。

如前所述,第二个问题是,如果您的视图是图层支持的,则您无法安全地在视图图层上设置变换/锚点。NSView每当几何形状发生变化时,都会重置图层的变换和锚点。如果视图是图层托管的,则允许您修改这些属性,但这会带来一系列您最可能希望避免的问题。您可以使用一些技巧来避免此问题,但它们需要调配,并且对于您不拥有的任何视图(例如)应该避免使用NSButton

所以我不得不问,为什么要让按钮变大一倍呢?缩放状态是短暂的,还是持久的?如果它是持久的,请改为更改框架。否则,如果它是瞬态的并且视图的几何形状没有改变,您可能可以修改这两个属性,因为 AppKit 在您完成动画之前没有理由重置它们。


编辑:您没有看到动画的原因是因为您的原始代码在同一事务中应用了两次缩放变换。当此事务合并修改时,它将选择最后应用的变换,这意味着它将是恒等变换,顺便说一下,应该写成CGAffineTransformIdentity而不是因子为 1 的比例变换。应用缩小比例通过将另一个动画块放入第一个动画的完成块中,在新事务中生成动画。例如:

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *ctx) {
        ctx.allowsImplicitAnimation = YES;
        layer.affineTransform = transform;
    } completionHandler:^{
        [NSAnimationContext runAnimationGroup:^(NSAnimationContext *ctx) {
            ctx.allowsImplicitAnimation = YES;
            layer.affineTransform = CGAffineTransformIdentity;
        } completionHandler:nil];
}];

在尝试动画 ( ) 之前,确保要缩放的子视图的父视图是图层支持的wantsLayer = YES

于 2015-04-04T06:49:02.977 回答