web-dev-qa-db-ja.com

CALayersは、UIViewの境界変更でサイズ変更されませんでした。どうして?

レイヤーに約8つの異なるUIViewサブレイヤーが追加されたCALayerがあります。 ビューの境界を変更する(アニメーション)の場合、ビュー自体は縮小します(backgroundColorで確認しました)、しかしサブレイヤーのサイズは変更されません

これを解決するには?

96
Geri

私はSolinが使用したのと同じアプローチを使用しましたが、そのコードにはタイプミスがあります。メソッドは次のとおりです。

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

私の目的のために、私は常にサブレイヤーを親ビューのフルサイズにしたかったのです。そのメソッドをビュークラスに配置します。

139
Chadwick Wood

IPhoneのCALayerはレイアウトマネージャーをサポートしていないため、ビューのメインレイヤーをlayoutSublayersをオーバーライドしてすべてのサブレイヤーのフレームを設定するカスタムCALayerサブクラスにする必要があると思います。また、ビューの+layerClassメソッドは、新しいCALayerサブクラスのクラスを返します。

25
Ole Begemann

これをUIViewで使用しました。

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

super.layoutSublayersOfLayer(layer)
}

私のために働く。

11
Runo Sahara

同じ問題がありました。カスタムビューのレイヤーに、さらに2つのサブレイヤーを追加しました。 (カスタムビューの境界が変更されるたびに)サブレイヤーのサイズを変更するために、カスタムビューのlayoutSubviewsメソッドを実装しました。このメソッド内では、サブビューのレイヤーの現在の境界に一致するように各サブレイヤーのフレームを更新するだけです。

このようなもの:

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

2017年

この質問に対する文字通りの答え:

「CALayersは、そのUIViewの境界変更でサイズ変更されませんでした。なぜですか?」

良くも悪くも

needsDisplayOnBoundsChange

CALayerのデフォルトはfalseです。

解決、

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を設定するときに、それを等しく設定する必要があります。

6
Fattie

Swift 3バージョン

カスタムセルで、次の行を追加

最初に宣言する

let gradientLayer: CAGradientLayer = CAGradientLayer()

次に、次の行を追加します

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

[Ole]が書いたように、CALayerはiOSでの自動サイズ変更をサポートしていません。そのため、レイアウトを手動で調整する必要があります。私のオプションは、レイヤーのフレームを調整することでした(iOS 7以前)

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

または(iOS 8以降)

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