107

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

如何解决这个问题?

4

8 回答 8

157

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

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

出于我的目的,我一直希望子层是父视图的全尺寸。将该方法放在您的视图类中。

于 2010-11-04T15:37:03.220 回答
27

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

于 2010-03-24T00:40:38.397 回答
16

我在 UIView 中使用了它。

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

super.layoutSublayersOfLayer(layer)
}

为我工作。

于 2015-02-27T03:39:11.057 回答
9

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

像这样的东西:

-(void)layoutSubviews{
   //keep the same origin, just update the width and height
   if(sublayer1!=nil){
      sublayer1.frame = self.layer.bounds;
   }
}
于 2010-07-28T08:21:09.827 回答
9

2017 年:

这个问题的字面答案:

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

是好是坏:

needsDisplayOnBoundsChange

默认为 false (!!) in CALayer

解决方案,

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
    }
}

确实,我将您引导至此 QA

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

这就解释了,批评者到底是做什么的contentsScale。当你设置needsDisplayOnBoundsChange.

于 2017-12-11T17:56:31.093 回答
5

斯威夫特 3 版本

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

先声明

let gradientLayer: CAGradientLayer = CAGradientLayer()

然后添加以下行

override func layoutSubviews() {
    gradientLayer.frame = self.YourCustomView.bounds
}
于 2017-06-08T10:38:17.947 回答
0

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

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

或(从 iOS 8 开始)

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinato
于 2015-03-01T12:59:02.493 回答
0

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

    类自定义视图:UIView {
        var customLayer:CALayer = CALayer()

        覆盖 func layoutSubviews() {
            super.layoutSubviews()
    // 守卫 let _fillColor = self._fillColor else {return}
            初始化布局()
        }
        私人函数初始化布局(){
            customLayer.removeFromSuperView()
            customLayer.frame = layer.bounds
                   
            layer.insertSubview(at:0)
        }
    }
于 2019-10-28T22:58:14.763 回答