【问题标题】:CALayer transform doesn't apply if NSView isn't created yet at the moment如果目前尚未创建 NSView,则 CALayer 转换不适用
【发布时间】:2015-11-23 10:37:34
【问题描述】:

环境:OS X 10.11 SDK、XCode 7.2、Cocoa;

上下文:在创建视图的那一刻应该应用一些复杂的转换;

当我尝试以编程方式添加 NSView 时,如果将变换属性放在 addSubview 调用之前,则会被忽略:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
   NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(100, 100, 100, 100)];
    CALayer* newLayer = [CALayer layer];

    newLayer.transform = CATransform3DMakeRotation(angle, 0.1f, 0.1f, 0.1f);

    [newLayer setBackgroundColor:[[NSColor greenColor] CGColor]];

    [view setLayer:newLayer];
    [view setWantsLayer:YES];
    [_window.contentView addSubview:view];
}

- (IBAction)click:(id)sender {
    angle += 0.1f;
    [[_window.contentView subviews] objectAtIndex:2].layer.transform = CATransform3DMakeRotation(angle, 0.1f, 0.1f, 0.1f);
    CATransform3D t = [[_window.contentView subviews] objectAtIndex:2].layer.transform;
    [[_window.contentView subviews] objectAtIndex:2].layer.edgeAntialiasingMask = !CATransform3DIsIdentity(t);
}

如果我点击按钮,视图会按原样旋转。此外,将视图添加到窗口后应用转换也可以:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(100, 100, 100, 100)];
    CALayer* newLayer = [CALayer layer];

    [newLayer setBackgroundColor:[[NSColor greenColor] CGColor]];

    [view setLayer:newLayer];
    [view setWantsLayer:YES];

    [_window.contentView addSubview:view];
    view.layer.transform = CATransform3DMakeRotation(angle, 0.1f, 0.1f, 0.1f);

} 

我是否遗漏了一些要求或只是误解了 CALayer 转换的工作原理?

【问题讨论】:

  • 这里有问题吗,或者您是否试图通过在 SO 上发布来提交错误报告?
  • @bhaller 添加了问题。我不认为这是一个错误,只是缺乏知识。
  • 如果 OS X 层的工作方式与 iOS 层的工作方式相同,这完全是预期行为。
  • @matt,也许我不清楚。刚刚创建的项目具有相同的原则:``` UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; view.layer.transform = CATransform3DMakeRotation(0.5f, 0.1f, 0.1f, 0.1f); [view.layer setBackgroundColor:[[UIColor greenColor] CGColor]]; [self.window.rootViewController.view addSubview:view]; ``` 而且它工作得很好(甚至在视图添加到 UIWindow 之前就已经应用了转换。
  • 嗯,是的,我明白你的意思了。但是在 Mac OS X 中,视图“拥有”了一个完全不同的层。iOS 视图天生就有一个层(没有层它们就不能存在),但不是每个 Mac OS X 视图都有一个;你必须要求它(就像你一样)。它更像是一个二等公民。

标签: macos cocoa calayer nsview appkit


【解决方案1】:

我提出的解决方案并不吸引人,但可以解决问题。我只是将转换推迟到视图初始渲染的那一刻。

@interface DebuggableView: NSView
    @property (nonatomic, assign) CATransform3D transform;
    @property (nonatomic, assign) bool shouldBeTransformed;
@end;

@implementation DebuggableView

- (instancetype) initWithFrame:(NSRect)frameRect
{
    self = [super initWithFrame:frameRect];
    if (self)
    {
        self.wantsLayer = YES;
    }
    return self;
}

- (void)layout
{
    [super layout];
    if (self.shouldBeTransformed) {
        self.layer.transform = self.transform;
        self.shouldBeTransformed = NO;
    }
}

@end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    相关资源
    最近更新 更多