可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
How to solve this?
回答1:
I used the same approach that Solin used, but there's a typo in that code. The method should be:
- (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.
回答2:
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.
回答3:
I used this in the UIView.
-(void)layoutSublayersOfLayer:(CALayer *)layer
{
if (layer == self.layer)
{
_anySubLayer.frame = layer.bounds;
}
super.layoutSublayersOfLayer(layer)
}
Works for me.
回答4:
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.
Something like this:
-(void)layoutSubviews{
//keep the same origin, just update the width and height
if(sublayer1!=nil){
sublayer1.frame = self.layer.bounds;
}
}
回答5:
2017
The literal answer to this question:
"CALayers didn't get resized on its UIView's bounds change. Why?"
is that for better or worse
needsDisplayOnBoundsChange
defaults to false in 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
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.
回答6:
Swift 3 Version
In Custom cell, Add Following lines
Declare first
let gradientLayer: CAGradientLayer = CAGradientLayer()
Then add following lines
override func layoutSubviews() {
gradientLayer.frame = self.YourCustomView.bounds
}
回答7:
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)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
or (as of iOS 8)
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinato
回答8:
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)
}
}