ios CALayer 没有在其 UIView 的边界变化时调整大小。为什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2504151/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:02:43  来源:igfitidea点击:

CALayers didn't get resized on its UIView's bounds change. Why?

iphoneiosobjective-cuiviewcalayer

提问by Geri Borbás

I have a UIViewwhich has about 8 different CALayersublayers added to its layer. If I modify the view's bounds(animated), then the view itself shrinks (I checked it with a backgroundColor), but the sublayers' size remains unchanged.

我有一个UIView它有大约 8 个不同的CALayer子层添加到它的层。如果我修改视图的边界(动画),则视图本身会缩小(我用 进行了检查backgroundColor),但子图层的大小保持不变

How to solve this?

如何解决这个问题?

回答by Chadwick Wood

I used the same approach that Solin used, but there's a typo in that code. The method should be:

我使用了与 Solin 相同的方法,但该代码中有一个错字。方法应该是:

- (void)layoutSubviews {
  [super layoutSubviews];
  // resize your layers based on the view's new bounds
  mylayer.frame = self.bounds;
}

For my purposes, I always wanted the sublayer to be the full size of the parent view. Put that method in your view class.

出于我的目的,我一直希望子层是父视图的完整大小。将该方法放在您的视图类中。

回答by Ole Begemann

Since CALayer on the iPhone does not support layout managers, I think you have to make your view's main layer a custom CALayer subclass in which you override layoutSublayersto set the frames of all sublayers. You must also override your view's +layerClassmethod to return the class of your new CALayer subclass.

由于 iPhone 上的 CALayer 不支持布局管理器,我认为您必须使视图的主层成为自定义 CALayer 子类,您可以在其中覆盖layoutSublayers以设置所有子层的框架。您还必须覆盖视图的+layerClass方法以返回新 CALayer 子类的类。

回答by Runo Sahara

I used this in the UIView.

我在 UIView 中使用了它。

-(void)layoutSublayersOfLayer:(CALayer *)layer
{
    if (layer == self.layer)
    {
        _anySubLayer.frame = layer.bounds;
    }

super.layoutSublayersOfLayer(layer)
}

Works for me.

为我工作。

回答by Solin

I had the same problem. In a custom view's layer I added two more sublayers. In order to resize the sublayers (every time the custom view's boundaries change), I implemented the method layoutSubviewsof my custom view; inside this method I just update each sublayer's frame to match the current boundaries of my subview's layer.

我有同样的问题。在自定义视图的图层中,我添加了另外两个子图层。为了调整子图层的大小(每次自定义视图的边界发生变化时),我实现了layoutSubviews自定义视图的方法;在这个方法中,我只是更新每个子图层的框架以匹配我的子视图图层的当前边界。

Something like this:

像这样的东西:

-(void)layoutSubviews{
   //keep the same origin, just update the width and height
   if(sublayer1!=nil){
      sublayer1.frame = self.layer.bounds;
   }
}

回答by Fattie

2017

2017年

The literal answer to this question:

这个问题的字面答案:

"CALayers didn't get resized on its UIView's bounds change. Why?"

“CALayers 没有因为 UIView 的边界变化而调整大小。为什么?”

is that for better or worse

是好是坏

needsDisplayOnBoundsChange

needsDisplayOnBoundsChange

defaults to false in CALayer.

中默认为 false CALayer

solution,

解决方案,

class CircularGradientViewLayer: CALayer {

    override init() {

        super.init()
        needsDisplayOnBoundsChange = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override open func draw(in ctx: CGContext) {
        go crazy drawing in .bounds
    }
}

Indeed, I direct you to this QA

确实,我将您引导至此 QA

https://stackoverflow.com/a/47760444/294884

https://stackoverflow.com/a/47760444/294884

which explains, what the hell the critical contentsScalesetting does; you usually need to equally set that when you set needsDisplayOnBoundsChange.

这解释了关键contentsScale设置到底做了什么;您通常需要在设置需要显示OnBoundsChange 时同样设置它。

回答by Vinay Krishna Gupta

Swift 3 Version

斯威夫特 3 版本

In Custom cell, Add Following lines

在自定义单元格中,添加以下行

Declare first

先申报

let gradientLayer: CAGradientLayer = CAGradientLayer()

Then add following lines

然后添加以下几行

override func layoutSubviews() {
    gradientLayer.frame = self.YourCustomView.bounds
}

回答by Lê T?n Thành

In your custom view, you need declare variable for your custom layer, don't declare variable in scope init. And just init it once time, don't try set null value and reinit

在您的自定义视图,您需要声明变量为您定制层,不初始化范围变量的声明。并且只初始化一次,不要尝试设置空值并重新初始化

    class CustomView:UIView {
        var customLayer:CALayer = CALayer()

        override func  layoutSubviews() {
            super.layoutSubviews()
    //        guard let _fillColor = self._fillColor else {return}
            initializeLayout()
        }
        private func initializeLayout() { 
            customLayer.removeFromSuperView()
            customLayer.frame = layer.bounds?                   
            layer.insertSubview(at:0)
        }
    }

回答by DevGansta

As [Ole] wrote CALayer does not support autoresizing on iOS. So you should adjust layout manually. My option was to adjust layer's frame within (iOS 7 and earlier)

正如 [Ole] 所写,CALayer 不支持在 iOS 上自动调整大小。所以你应该手动调整布局。我的选择是在(iOS 7 及更早版本)内调整图层的框架

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 

or (as of iOS 8)

或(从 iOS 8 开始)

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinato