CGAffineTransformMakeScale 不工作 - OS X - Cocoa

Sup*_*off 0 macos cocoa animation transform nsanimation

我正在开发一个简单的 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];
Run Code Online (Sandbox Code Playgroud)

更新 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...");
        }];
    }];
Run Code Online (Sandbox Code Playgroud)

更新 2

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

我的头 (.h) 文件:

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

@interface ViewController : NSViewController {

    IBOutlet NSButton *numberButton1;
}

-(IBAction)demo:(id)sender;

@end
Run Code Online (Sandbox Code Playgroud)

我的实现(.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
Run Code Online (Sandbox Code Playgroud)

我也不会Auto Layout我的UI文件。

谢谢,丹。

sud*_*-rf 5

affineTransform属性 onCALayer只是该属性的便利包装器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];
}];
Run Code Online (Sandbox Code Playgroud)

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