web-dev-qa-db-ja.com

iOS 7でシート/アラートが表示されているときに、カスタム描画されたコントロールでtintColorを灰色にアニメーション化するにはどうすればよいですか?

IOS 7では、UIActionSheetが提示されると、システムはすべてのtintColorを灰色にアニメートします。シートが閉じられると、アニメーションで元に戻ります。

色付きの色を使用するカスタム背景画像またはdrawRect実装を備えたコントロールがいくつかあります。システムコントロールと同じように、その変化をアニメーション化したいと思います。

Appleは- (void)tintColorDidChangeUIViewに追加しましたが、このメソッドで新しい色で再描画しても、変更はアニメーション化されません。フルカラーからフルグレーにすぐに切り替わるだけで、他のシステムでは見栄えが悪くなります。その周りのコントロールはアニメーションです。

カスタム描画されたコントロールをAppleのようにtintColor遷移をアニメーション化するにはどうすればよいですか?

34
Marco

これは、ビューレイヤーに適用された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];

編集:再描画の方法によっては、アニメーションと再描画の間に競合状態が発生する場合があります。すぐに更新された(アニメーションなしで)試した元の再描画コードを投稿できる場合は、より具体的な回答を提供できます。

28
Nick Lockwood

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;
    }];
}
7
onmyway133

新しい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インスタンスで自動的にアニメーション化されます。

6
Matt Zanchelli