34

在 iOS 7 中,当出现 a 时UIActionSheet,系统控件都将其设置tintColor为灰色。当工作表被关闭时,它们会返回动画。

我有一些带有自定义背景图像的控件或drawRect使用 tint 颜色的实现,我希望它们像系统控件一样为更改设置动画。

Apple 添加- (void)tintColorDidChangeUIView,但在此方法中使用新颜色重绘并不会为更改设置动画 - 它只是立即从全色切换到全灰色,当它周围的其他系统控件正在设置动画时,这看起来很糟糕。

如何让我的自定义绘制控件tintColor像 Apple 那样为过渡设置动画?

4

3 回答 3

28

你可以通过应用到视图层的核心动画过渡来做到这一点:

//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];

编辑:动画和重绘之间可能存在竞争条件,具体取决于您如何进行重绘。如果您可以发布您尝试立即更新的原始重绘代码(没有动画),我可以提供更具体的答案。

于 2013-11-05T21:05:50.760 回答
7

你试过tintAdjustmentMode吗?

您应该观看WWDC 2013 Session 214 Customizing Your App's Appearance for iOS 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;
    }];
}
于 2014-02-24T06:19:50.760 回答
6

drawRect:应该自动调用动画来更新新的tintColor

我制作了一个演示应用程序,在主视图控制器中有三个控件。第一个是调出标准操作表的按钮。第二个是用于观察的按钮(在动画期间很难与点击的按钮进行比较)。第三个是自定义UIView子类,它简单地绘制视图的tintColor. 当tintColorDidChange被调用时,我调用setNeedsDisplay,而后者又会调用drawRect:

我用一个视图控制器创建了一个新应用程序:

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

whereTESTCustomView是一个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视图控制器中的标准实例进行动画处理。

于 2013-11-05T21:39:35.483 回答