在窗口调整大小时调整CALayer框架大小的方法?

查理

我将一系列图像绘制到各个CALayer子层,然后将这些子层添加到中superlayer

- (void)renderImagesFromArray:(NSArray *)array {
    CALayer *superLayer = [CALayer layer];
    for (id object in array) {
        CALayer* subLayer = [CALayer layer];
        // Disregard...
        NSURL *path = [NSURL fileURLWithPathComponents:@[NSHomeDirectory(), @"Desktop", object]];
        NSImage *image = [[NSImage alloc] initWithContentsOfURL:path];
        [self positionImage:image layer:subLayer];
        subLayer.contents = image;
        subLayer.hidden = YES;
        [superLayer addSublayer:subLayer];
    }
    [self.view setLayer:superLayer];
    [self.view setWantsLayer:YES];
    // Show top layer
    CALayer *top = superLayer.sublayers[0];
    top.hidden = NO;
}

然后[self positionImage: layer:]我调用将其拉伸CALayer到最大范围(本质上使用CSScover属性的算法),并将其放置在窗口的中央:

- (void)positionImage:(NSImage *)image layer:(CALayer *)layer{
    float imageWidth = image.size.width;
    float imageHeight = image.size.height;
    float frameWidth = self.view.frame.size.width;
    float frameHeight = self.view.frame.size.height;
    float aspectRatioFrame = frameWidth/frameHeight;
    float aspectRatioImage = imageWidth/imageHeight;
    float computedImageWidth;
    float computedImageHeight;
    float verticalSpace;
    float horizontalSpace;
    if (aspectRatioImage <= aspectRatioFrame){
        computedImageWidth = frameHeight * aspectRatioImage;
        computedImageHeight = frameHeight;
        verticalSpace = 0;
        horizontalSpace = (frameWidth - computedImageWidth)/2;
    } else {
        computedImageWidth = frameWidth;
        computedImageHeight = frameWidth / aspectRatioImage;
        horizontalSpace = 0;
        verticalSpace = (frameHeight - computedImageHeight)/2;
    }
    [CATransaction flush];
    [CATransaction begin];
    CATransaction.disableActions = YES;
    layer.frame = CGRectMake(horizontalSpace, verticalSpace, computedImageWidth, computedImageHeight);
    [CATransaction commit];
}

一切正常,除非调整窗口大小。我通过子类化(以非常丑陋的方式)解决了这个问题NSView,然后实现了在调整窗口大小时实际调用的唯一方法viewWillDraw:

- (void)viewWillDraw{
    [super viewWillDraw];
    [self redraw];
}

- (void)redraw{
    AppDelegate *appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
    CALayer *superLayer = self.layer;
    NSArray *sublayers = superLayer.sublayers;
    NSImage *image;
    CALayer *current;
    for (CALayer *view in sublayers){
        if (!view.isHidden){
            current = view;
            image = view.contents;
        }
    }
    [appDelegate positionImage:image layer:current];
}

那么...什么是正确的方法呢?viewWillDraw:get的调用次数过多,这意味着我必须执行不必要的和多余的计算,并且我无法使用,viewWillStartLiveResize:因为我需要不断将图像保持在正确的位置。我在俯视什么?

查理

彼得·霍西(Peter Hosey)是对的;我原来的方法笨拙,我不应该压倒一切setNeedsDisplayInRect:我首先确保我在我的应用程序中使用了自动布局,然后实施了以下操作:

subLayer.layoutManager  = [CAConstraintLayoutManager layoutManager];
subLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable;
subLayer.contentsGravity = kCAGravityResizeAspect;

基本上,我将子层设置为autoResizingMask水平和垂直拉伸,然后设置contentsGravity为保留宽高比。

我偶然发现了最后一个变量,但值得注意的是,如果仅将几个contentsGravity常量用于,例如在我的情况下,将a设置NSImage为图层的contents

该方法创建的图像适合用作图层的内容,并且支持该图层的所有重力模式。相比之下,NSImage类仅支持kCAGravityResize,kCAGravityResizeAspect和kCAGravityResizeAspectFill模式。

当复杂的解决方案可以简化为3行代码时,总是很有趣。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ScalaFX(JavaFX):舞台内容不会在窗口调整大小时调整大小

来自分类Dev

在窗口调整大小时调整两个图片框的大小

来自分类Dev

CSS在窗口调整大小时调整div和div内的图像

来自分类Dev

在窗口调整大小时隐藏元素

来自分类Dev

页眉在窗口调整大小时移动

来自分类Dev

函数仅在窗口调整大小时调用一次

来自分类Dev

在窗口调整大小时重新运行jQuery插件实例

来自分类Dev

jQuery .remove()不删除(在窗口调整大小时)

来自分类Dev

jQuery Toggle在窗口调整大小时不显示

来自分类Dev

在窗口调整大小时触发jQuery插件吗?

来自分类Dev

如何防止导航栏在窗口调整大小时转移?

来自分类Dev

如何在窗口调整大小时覆盖我的数组?

来自分类Dev

Java在窗口调整大小时反跳和限制

来自分类Dev

vuejs在窗口调整大小时获取参考元素的高度

来自分类Dev

removeClass()在窗口调整大小时不起作用

来自分类Dev

画布-在窗口调整大小时转换鼠标坐标

来自分类Dev

如何防止导航栏在窗口调整大小时转移?

来自分类Dev

在窗口调整大小时刷新SVG坐标

来自分类Dev

水平对齐div,在窗口调整大小时停止浮动

来自分类Dev

在窗口调整大小时更新角度服务变量

来自分类Dev

Java在窗口调整大小时反跳和限制

来自分类Dev

如何在窗口调整大小时重绘画布

来自分类Dev

同时调整 JPanel 大小时调整图像大小

来自分类Dev

在调整窗口大小时调用多个函数

来自分类Dev

<p:sticky>在窗口调整大小时不会调整大小

来自分类Dev

高图图表在窗口调整大小时无法正确调整大小

来自分类Dev

调整窗口高度时调整图像的大小

来自分类Dev

调整窗口高度时调整图像的大小

来自分类Dev

使用 resizeEvent 调整窗口大小时调整 Qlabel 图像大小

Related 相关文章

  1. 1

    ScalaFX(JavaFX):舞台内容不会在窗口调整大小时调整大小

  2. 2

    在窗口调整大小时调整两个图片框的大小

  3. 3

    CSS在窗口调整大小时调整div和div内的图像

  4. 4

    在窗口调整大小时隐藏元素

  5. 5

    页眉在窗口调整大小时移动

  6. 6

    函数仅在窗口调整大小时调用一次

  7. 7

    在窗口调整大小时重新运行jQuery插件实例

  8. 8

    jQuery .remove()不删除(在窗口调整大小时)

  9. 9

    jQuery Toggle在窗口调整大小时不显示

  10. 10

    在窗口调整大小时触发jQuery插件吗?

  11. 11

    如何防止导航栏在窗口调整大小时转移?

  12. 12

    如何在窗口调整大小时覆盖我的数组?

  13. 13

    Java在窗口调整大小时反跳和限制

  14. 14

    vuejs在窗口调整大小时获取参考元素的高度

  15. 15

    removeClass()在窗口调整大小时不起作用

  16. 16

    画布-在窗口调整大小时转换鼠标坐标

  17. 17

    如何防止导航栏在窗口调整大小时转移?

  18. 18

    在窗口调整大小时刷新SVG坐标

  19. 19

    水平对齐div,在窗口调整大小时停止浮动

  20. 20

    在窗口调整大小时更新角度服务变量

  21. 21

    Java在窗口调整大小时反跳和限制

  22. 22

    如何在窗口调整大小时重绘画布

  23. 23

    同时调整 JPanel 大小时调整图像大小

  24. 24

    在调整窗口大小时调用多个函数

  25. 25

    <p:sticky>在窗口调整大小时不会调整大小

  26. 26

    高图图表在窗口调整大小时无法正确调整大小

  27. 27

    调整窗口高度时调整图像的大小

  28. 28

    调整窗口高度时调整图像的大小

  29. 29

    使用 resizeEvent 调整窗口大小时调整 Qlabel 图像大小

热门标签

归档