【问题标题】:add UIImage in CALayer在 CALayer 中添加 UIImage
【发布时间】:2012-10-27 16:10:19
【问题描述】:

我必须添加一个 UIImageView 作为 MapView 的子视图。为此,我在 MapView 上方创建了一个图层。在这一层中,我想放置我的图像,但我得到一个白色矩形,没有别的。我的图像不可见。

这是代码:

- (void)viewDidLoad
{
    //......

    CALayer *layer = [CALayer layer];
    layer.backgroundColor = [[UIColor whiteColor] CGColor];

    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        layer.bounds = CGRectMake(self.mapView.bounds.origin.x,
                                  self.mapView.bounds.origin.y, 80, 300);
    }
    else
    {
        layer.bounds = CGRectMake(self.mapView.frame.origin.x,
                                  self.mapView.frame.origin.y, 150, 700);
    }

    layer.contents = (id)[UIImage imageNamed:@"myImage.png"];
    //the name is correct but  in the output the image is not visible

    [[self.mapView layer] addSublayer:layer];
    [layer setNeedsDisplay];
}

【问题讨论】:

    标签: ios uiimageview uiimage calayer subview


    【解决方案1】:

    应该是的

    layer.contents = (id)[UIImage imageNamed:@"myImage.png"].CGImage;
    

    你只能将CGImage放入图层,不能直接放入UIImage。

    【讨论】:

      【解决方案2】:

      我删除了

       [layer setNeedsDisplay];
      

      我不知道为什么,但它有效!

      【讨论】:

      • 我猜是 setNeedsDisplay 使图层重绘内容,因此删除了图像。
      • 为此加一个。它肯定会触发重绘(我认为它需要),但在重绘之前它会丢弃content。
      【解决方案3】:

      你需要正确设置CALayer的框架,因为默认是CGRectZero。

      【讨论】:

        【解决方案4】:

        为了未来的观众,这是一个一般性的答案。它基于问题标题而不是原始问题的详细信息。

        如何将 UIImage 添加到 CALayer

        您可以通过使用视图的contents 属性将图像添加到视图的layer:

        myView.layer.contents = UIImage(named: "star")?.cgImage
        
        • 请注意,UIImage 需要转换为 CGImage。

        如果你想在自己的图层中添加图像,你可以这样做:

        let myLayer = CALayer()
        let myImage = UIImage(named: "star")?.cgImage
        myLayer.frame = myView.bounds
        myLayer.contents = myImage
        myView.layer.addSublayer(myLayer)
        

        修改外观

        上面的代码产生了一个这样的视图。浅蓝色是UIView,深蓝色星是UIImage。

        不过,正如您所见,它看起来像素化了。这是因为UIImage 比UIView 小,所以它被缩放以填充视图,这是默认设置,您没有指定任何其他内容。

        以下示例显示了图层 contentsGravity 属性的变化。代码如下所示:

        myView.layer.contents = UIImage(named: "star")?.cgImage
        myView.layer.contentsGravity = kCAGravityTop
        myView.layer.isGeometryFlipped = true
        

        在 iOS 中,如果您使用顶部或底部重力做任何事情,您可能需要将 isGeometryFlipped property 设置为 true,否则它将与您的预期相反。 (只有重力垂直翻转,没有内容渲染。如果您在翻转内容时遇到问题,请参阅this answer。)

        对于每个contentsGravity 设置,下面有两个UIView 示例,一个视图大于UIImage,另一个视图较小。这样您就可以看到缩放和重力的效果。

        kCAGravityResize

        这是默认设置。

        kCAGravityResizeAspect

        kCAGravityResizeAspectFill

        kCAGravityCenter

        kCAGravityTop

        kCAGravityBottom

        kCAGravityLeft

        kCAGravityRight

        kCAGravityTopLeft

        kCAGravityTopRight

        kCAGravityBottomLeft

        kCAGravityBottomRight

        相关

        【讨论】:

        • 很好的答案。但是如何同时进行 kCAGravityResizeAspectFill 和 kCAGravityTop 呢?
        • 将 contentsRect 调整到正确的比例就可以了。另一种选择是使用 UIImageView 作为 UIView maskView。
        • 很棒的教程好友@suragch 让我永远发现.gravity 是您设置方面适合/填充/等的地方。请注意,有趣的是,当前的 Apple doco 是完全错误的,它没有提到这些选项!主文档页面仅提及调整大小/居中/翻转。奇怪!
        • 所有人的补充:layer.contentsGravity = view.contentMode
        • 为了防止图像被渲染到应有的 x2 或 x3 倍,您应该设置 CALayer 的比例以匹配屏幕的比例: layer.contentsScale = UIScreen.main.scale
        【解决方案5】:

        myView.layer.contents = UIImage(named: "star")?.cgImage

        【讨论】:

        • 请在您的回答中提供更多详细信息。即使你的答案是一个完整的解决方案,如果你花时间解释你的代码是做什么的,以及你是如何想出它的,提问者也会学到更多。
        • @Jolta 我认为没有更多细节可以添加到 OP 的答案中。这是代码。
        【解决方案6】:

        2020,完整的简单示例

        在本例中,图像只是整体视图的大小:

        class ImageyView: UIView {
            
            private lazy var im: CALayer = {
                let l = CALayer()
                l.contents = UIImage(named: "some_background")?.cgImage
                l.contentsGravity = .resizeAspect
                layer.addSublayer(l)
                return l
            }()
            
            override func layoutSubviews() {
                super.layoutSubviews()
                im.frame = bounds
            }
        }
        

        在本例中,它是一个按钮,您在左上角添加了一个小图标:

        class BroadcastButton: UIButton {
            
            private lazy var im: CALayer = {
                let l = CALayer()
                l.contents = UIImage(named: "your_icon")?.cgImage
                l.contentsGravity = .resizeAspect
                layer.addSublayer(l)
                return l
            }()
            
            override func layoutSubviews() {
                super.layoutSubviews()
                im.frame = CGRect(origin: CGPoint(x: 2, y: 2),
                     size: CGSize(width: 14, height: 14))
            }
        }
        

        【讨论】:

          【解决方案7】:

          这应该是一个评论,但我浪费了几个小时,所以我把它作为一个独立的答案。

          我在做:

          myView.layer.contents = UIImage(named: "star")
          

          你能找出问题所在吗?因为contents 是Any 类型,所以编译得很好。但正确的代码是:

          myView.layer.contents = UIImage(named: "star").cgImage
          

          【讨论】:

            猜你喜欢
            • 2016-02-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-01-31
            • 1970-01-01
            • 2013-12-13
            • 2013-04-05
            • 1970-01-01
            相关资源
            最近更新 更多