【问题标题】:CGAffineTransformMakeScale not working - OS X - CocoaCGAffineTransformMakeScale 不工作 - OS X - Cocoa
【发布时间】:2015-04-03 09:39:26
【问题描述】:

我正在开发一个简单的 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

我也在我的 UI 文件中使用 Auto Layout

谢谢,丹。

【问题讨论】:

    标签: macos cocoa animation transform nsanimation


    【解决方案1】:

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

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

    如前所述,第二个问题是,如果您的视图是图层支持的,则您无法安全地在视图的图层上设置变换/锚点。 NSView 将在几何图形发生变化时重置图层的变换和锚点。如果视图是图层托管的,您可以修改这些属性,但这会带来一系列您很可能希望避免的问题。您可以使用一些 hacks 来避免此问题,但它们需要调配,并且对于您不拥有的任何视图(例如 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)。

    【讨论】:

    • 您好,非常感谢您的回答。所以基本上我正在制作一个游戏,当用户按下 NSButton 时,我希望它放大然后再变小。这只是我想要在应用程序中的一个有趣的简单小动画。
    • 我将allowImplicitAnimation设置为YES,虽然现在动画很流畅,但它仍然没有放大按钮。
    • 你好。我一直在玩这个,但我仍然没有设法让它工作。有关我的代码,请参阅我更新的问题。你有什么过分的想法吗?
    • 在您的上下文中启用allowsImplicitAnimation
    • 好的,帮助很大!我快到了。我遇到的最后一个问题是,当动画发生时,它似乎只放大了 NSButton 文本。我希望它放大整个 NSButton。我之前在 iOS 上使用 UIButton 完成了这个动画,所以我知道它可以工作。我只是想让整个按钮变大,所以它的视图需要放大(不仅仅是它的文本标签)。我该怎么做?
    猜你喜欢
    • 2015-01-05
    • 2016-05-31
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多