CALayers didn't get resized on its UIView'

2020-01-26 02:55发布

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?

8条回答
虎瘦雄心在
2楼-- · 2020-01-26 03:35

I used this in the UIView.

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

super.layoutSublayersOfLayer(layer)
}

Works for me.

查看更多
太酷不给撩
3楼-- · 2020-01-26 03:37

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.

查看更多
爷、活的狠高调
4楼-- · 2020-01-26 03:44

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
}
查看更多
等我变得足够好
5楼-- · 2020-01-26 03:45

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.

查看更多
▲ chillily
6楼-- · 2020-01-26 03:48

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)
        }
    }
查看更多
做自己的国王
7楼-- · 2020-01-26 03:50

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
查看更多
登录 后发表回答