如何在Mac上与图层支持的视图进行交互

时间:2011-05-05 10:28:16

标签: objective-c macos core-animation calayer

我正在设计一个包含多个标签和文本字段的用户界面。我想像这样设置UI:

  1. 为我的NSWindow
  2. 的内容视图设置背景图案
  3. 在左上角的背景中添加自定义图标
  4. 我通过使内容视图成为图层支持的视图解决了第一个问题,如Apple's documentation of NSView中所述:

      

    图层支持的视图是由Core Animation图层支持的视图。视图完成的任何绘制都将缓存在背衬层中。您只需使用值setWantsLayer:调用YES来配置图层支持的视图。视图类将自动为您创建背衬层,并使用视图类的绘制机制。 使用图层支持的视图时,不应直接与图层进行交互。

         

    图层托管视图是一个视图,其中包含您要直接操作的Core Animation图层。您可以通过实例化Core Animation图层类的实例并使用视图的setLayer:方法设置该图层来创建图层托管视图。完成后,您可以使用值setWantsLayer:调用YES使用图层托管视图时,不应依赖视图进行绘制,也不应将子视图添加到图层托管视图。

    然后从CGColorRef中生成CGPattern来绘制我的CGImage

    NSView *mainView = [[self window]contentView];
    [mainView setWantsLayer:YES];
    

    要将背景图像设置为模式,我在此处使用How to tile the contents of a CALayer的答案来完成第一项任务。

    但是对于第二项任务,添加图标我使用下面的代码:

    CGImageRef iconImage = NULL;
    NSString *path = [[NSBundle mainBundle] pathForResource:@"icon_128" ofType:@"png"];
    if(path != nil) {
        NSURL *imageURL = [NSURL fileURLWithPath:path];
        provider = CGDataProviderCreateWithURL((CFURLRef)imageURL);
        iconImage = CGImageCreateWithPNGDataProvider(provider,NULL,FALSE,kCGRenderingIntentDefault); 
        CFRelease(provider);
    }
    CALayer *iconLayer = [[CALayer alloc] init];
    // layer is the mainView's layer
    CGRect layerFrame = layer.frame;
    CGFloat iconWidth = 128.f;
    iconLayer.frame = CGRectMake(0.f, CGRectGetHeight(layerFrame)-iconWidth, 128.f, 128.f);
    iconLayer.contents = (id)iconImage;
    CGImageRelease(iconImage);
    [layer insertSublayer:iconLayer  atIndex:0];
    [iconLayer release];
    

    问题

    1. 我不确定我是否违反了Apple对图层支持的视图的限制,您不应该直接与该图层进行交互。设置图层的背景颜色时直接与图层交互,或者我在这里弄错了?
    2. 我很难直接与图层支持的视图的图层层次结构进行交互,并像我为第二个任务插入一个新图层。这可能还是违反Apple的指导方针?我想指出,这个内容视图当然有几个子视图,如标签,文本视图和按钮。
    3. 在我看来,只使用一个图层托管 NSView似乎是最干净的解决方案。然后可以将所有文本标签添加为CATextLayers等。但是,如果我正确理解Apple的文档,则无法再向视图添加任何控件。我是否必须在自定义CALayers中自行编码所有控件以使其正常工作?听起来像重新发明轮子 de luxe 。我也不知道如何仅在CoreAnimation中对NSTextField进行编码。
    4. 有关如何使用CoreAnimation和标准控件分割设计用户界面的任何建议都很受欢迎。

      请注意我在这里谈论Mac。

2 个答案:

答案 0 :(得分:1)

不需要层支持恕我直言:

for 1.我做一个模式图像

NSImage *patternImage = [NSImage imageNamed:@"pattern"];
[window setBackgroungdColor:[NSColor colorWithPatternImage:patternImage]];

for 2.添加NSImageView作为contentview的子视图

NSImageView *v = ...
[[window contentView] addSubview:v]; 

某些视图上的

不能很好地响应IF层支持 ::例如pdfview

答案 1 :(得分:0)

创建一个superview容器A.将子视图B添加到A以满足所有NSView需求(按钮等)。将子视图C添加到A以满足您的所有核心动画需求。

编辑: 更好的是:使用superview A满足所有NSView需求,使用一个子视图C满足你的Core Animation需求,完全忽略视图B.