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
CALayers didn't get resized on its UIView's bounds change. Why?
提问by Geri Borbás
I have a UIView
which has about 8 different CALayer
sublayers 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 layoutSublayers
to set the frames of all sublayers. You must also override your view's +layerClass
method 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 layoutSubviews
of 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 contentsScale
setting 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