レイヤー (グラデーション レイヤーなど) を作成する場合、レイヤーを管理するビューはありません (ビューのレイヤーのサブレイヤーとして追加する場合でも)。UIView
このようなスタンドアロン レイヤは、アニメーション システムに参加しません。
そのため、グラデーション レイヤーのフレームを更新すると、レイヤーは独自のデフォルト アニメーション パラメータを使用して変更をアニメーション化します。(これは「暗黙のアニメーション」と呼ばれます。) これらの既定のパラメーターは、インターフェイスの回転に使用されるアニメーションのパラメーターと一致しないため、奇妙な結果が得られます。
私はあなたのプロジェクトを見ていませんでしたが、このコードで問題を再現するのは簡単です:
@interface ViewController ()
@property (nonatomic, strong) CAGradientLayer *gradientLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.gradientLayer = [CAGradientLayer layer];
self.gradientLayer.colors = @[ (__bridge id)[UIColor blueColor].CGColor, (__bridge id)[UIColor blackColor].CGColor ];
[self.view.layer addSublayer:self.gradientLayer];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.gradientLayer.frame = self.view.bounds;
}
@end
シミュレーターでスローモーションを有効にすると、次のようになります。
幸いなことに、これは簡単に修正できる問題です。グラデーション レイヤーをビューで管理する必要があります。これを行うには、をレイヤーとしてUIView
使用するサブクラスを作成します。CAGradientLayer
コードは小さいです:
// GradientView.h
@interface GradientView : UIView
@property (nonatomic, strong, readonly) CAGradientLayer *layer;
@end
// GradientView.m
@implementation GradientView
@dynamic layer;
+ (Class)layerClass {
return [CAGradientLayer class];
}
@end
GradientView
次に、コードをの代わりに使用するように変更する必要がありますCAGradientLayer
。レイヤーの代わりにビューを使用しているため、自動サイズ変更マスクを設定して、グラデーションのサイズをそのスーパービューに維持できるため、後で回転を処理するために何もする必要はありません。
@interface ViewController ()
@property (nonatomic, strong) GradientView *gradientView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.gradientView = [[GradientView alloc] initWithFrame:self.view.bounds];
self.gradientView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.gradientView.layer.colors = @[ (__bridge id)[UIColor blueColor].CGColor, (__bridge id)[UIColor blackColor].CGColor ];
[self.view addSubview:self.gradientView];
}
@end
結果は次のとおりです。