2015-04-03 8 views
0

У меня есть простое приложение Mac, которое я разрабатываю. Я хочу иметь возможность применить преобразование в NSButton и сделать его больше. Дважды его размер. Однако мой код не работает, он просто перемещает кнопку в угол. Кто-нибудь знает, что не так?CGAffineTransformMakeScale не работает - OS X - Cocoa

[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]; 

Update 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..."); 
     }]; 
    }]; 

Update 2

Вот мой код Судо не делать, надеюсь, это поможет:

Мой заголовок (.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.

Спасибо, Дэн.

ответ

2

Недвижимость affineTransform на CALayer является просто удобной упаковкой для transform. В режимах с поддержкой слоя вы не должны изменять это. Это, как говорится, возможно.

Первой из ваших проблем является то, что вы не можете анимировать свойства слоя с помощью блока NSAnimation. Вам нужно явно создать объект CABasicAnimation, который представляет анимацию преобразования и добавить ее к слою. Редактировать: Я просто вспомнил, что на самом деле возможно анимировать свойства слоя. Вам нужно включить свойство allowsImplicitAnimation в контексте. Целью этого свойства является предоставление возможности просмотра свойств представления без использования прокси-сервера аниматора, но побочным эффектом является то, что он позволяет анимировать неявные свойства слоя.

Вторая проблема, как было сказано выше, заключается в том, что вы не можете безопасно установить точку преобразования/привязки на уровне представления, если ваше представление поддерживает слой. NSView сбрасывает преобразование вашего слоя и точку привязки всякий раз, когда изменяется геометрия. Вы можете изменить эти свойства, если представление является хостингом на уровне, но это связано с целым рядом проблем, которые вы, скорее всего, захотите избежать. Есть некоторые hacks, которые вы можете использовать, чтобы избежать этой проблемы, но они требуют swizzling и, вероятно, следует избегать для любых видов, которые у вас нет (например, NSButton).

Так что я должен спросить, почему вы хотите сделать кнопку вдвое больше? Является ли масштабированное состояние эфемерным, или оно устойчиво? Если это постоянно, замените рамку. В противном случае, если это временно, а геометрия представления не изменится, вы можете уйти с изменением двух свойств, так как AppKit не будет иметь причины для их сброса до завершения анимации.


Edit: Причина, почему вы не видите анимации, потому что исходный код применяет масштаб в два раза преобразования в той же транзакции.Когда эта транзакция будет модифицирована, она подберет последнее примененное преобразование, то есть это будет преобразование идентичности, которое, кстати, должно быть записано как 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).

+0

Привет, большое спасибо за ваш ответ. Поэтому в основном я делаю игру, и когда пользователь нажимает на NSButton, я хочу, чтобы он увеличился, а затем снова стал меньше. Это просто приятная забавная простая анимация, которую я хочу в приложении. – Supertecnoboff

+0

Я установил allowImplicitAnimation на YES, и пока анимация теперь гладкая, она все еще не увеличивает кнопку. – Supertecnoboff

+0

То, что вы делаете, не будет работать. См. Мое редактирование. –