IOS 7では、UIActionSheet
が提示されると、システムはすべてのtintColor
を灰色にアニメートします。シートが閉じられると、アニメーションで元に戻ります。
色付きの色を使用するカスタム背景画像またはdrawRect
実装を備えたコントロールがいくつかあります。システムコントロールと同じように、その変化をアニメーション化したいと思います。
Appleは- (void)tintColorDidChange
をUIView
に追加しましたが、このメソッドで新しい色で再描画しても、変更はアニメーション化されません。フルカラーからフルグレーにすぐに切り替わるだけで、他のシステムでは見栄えが悪くなります。その周りのコントロールはアニメーションです。
カスタム描画されたコントロールをAppleのようにtintColor
遷移をアニメーション化するにはどうすればよいですか?
これは、ビューレイヤーに適用されたCoreAnimationトランジションで実行できます。
//set up transition
CATransition *transition = [CATransition animation];
transition.type = kCATransitionFade;
transition.duration = 0.4;
[self.layer addAnimation:transition forKey:nil];
//now trigger a redraw of the background using the new colour
//and the transition will cover the redraw with a crossfade
self.flagToIndicateColorShouldChange = YES;
[self setNeedsDisplay];
編集:再描画の方法によっては、アニメーションと再描画の間に競合状態が発生する場合があります。すぐに更新された(アニメーションなしで)試した元の再描画コードを投稿できる場合は、より具体的な回答を提供できます。
tintAdjustmentMode
を試しましたか?
WWDC2013セッション214iOS 7用のアプリの外観のカスタマイズ を見て、 TicTacToeデモアプリ を読む必要があります。
このようなもの
- (void)onPopupOpened
{
[UIView animateWithDuration:0.3 animations:^{
window.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
}];
popupView.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
popupView.tintColor = [UIColor redColor];
}
- (void)onPopupClosed
{
[UIView animateWithDuration:0.3 animations:^{
window.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;
}];
}
新しいtintColor
のアニメーションを更新するためにdrawRect:
を自動的に呼び出す必要はありませんか?
メインビューコントローラーに3つのコントロールがあるデモアプリケーションを作成しました。 1つ目は、標準のアクションシートを表示するボタンです。 2つ目は、観察用にあるボタンです(タップされたボタンは、アニメーション中に比較するのが難しいです)。 3つ目は、ビューのUIView
の長方形を描画するだけのカスタムtintColor
サブクラスです。 tintColorDidChange
が呼び出されると、setNeedsDisplay
が呼び出され、次にdrawRect:
が呼び出されます。
1つのView Controllerで新しいアプリケーションを作成しました。
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[UIApplication sharedApplication] keyWindow].tintColor = [UIColor blueColor];
// Button to bring up action sheet
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = (CGRect){10,30,300,44};
[button setTitle:@"Present Action Sheet" forState:UIControlStateNormal];
[button addTarget:self
action:@selector(didTapPresentActionSheetButton:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
// Another button for demonstration
UIButton *anotherButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
anotherButton.frame = (CGRect){10,90,300,44};
[anotherButton setTitle:@"Another Button" forState:UIControlStateNormal];
[self.view addSubview:anotherButton];
// Custom view with tintColor
TESTCustomView *customView = [[TESTCustomView alloc] initWithFrame:(CGRect){10,150,300,44}];
[self.view addSubview:customView];
}
- (void)didTapPresentActionSheetButton:(id)sender
{
UIActionSheet *as = [[UIActionSheet alloc] initWithTitle:@"Action Sheet"
delegate:nil
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:@"Delete"
otherButtonTitles:@"Other", nil];
[as showInView:self.view];
}
ここで、TESTCustomView
は、次のように実装されたUIView
サブクラスです。
- (void)drawRect:(CGRect)rect
{
NSLog(@"Drawing with tintColor: %@", self.tintColor);
// Drawing code
[super drawRect:rect];
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(c, self.tintColor.CGColor);
CGContextFillRect(c, rect);
}
- (void)tintColorDidChange
{
[self setNeedsDisplay];
}
このアプリケーションをシミュレーターで実行すると、カスタムビューのtintColorが、ビューコントローラーの標準のUIButton
インスタンスで自動的にアニメーション化されます。