iphone - 在 iOS 上,自定义 View 不会设置动画?

标签 iphone ios uiview core-animation uiviewanimation

在一个新的单 View 应用程序中,以下代码:

- (void)viewDidAppear:(BOOL)animated {
    self.fooView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    self.fooView.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:self.fooView];

    [UIView animateWithDuration:2 animations:^{
        self.fooView.backgroundColor = [UIColor blueColor];
    }];
}

会将黄色背景动画化为蓝色。 fooView 只是:

@property (strong, nonatomic) UIView *fooView;

但是如果定义了自定义 View 类FooView,并且我通过将UIView替换为FooView来更改上面的代码,并且还定义了为 FooView 设置一个空的 -drawRect,然后将没有动画——背景立即变为蓝色。

如果使用 [UIView animateWithDuration: ...][FooView animateWithDuration: ...] 没有区别——它不是动画。

如果在 -drawRect 中,我调用 [super drawRect:rect];,那么它是一样的:没有动画。

如果我将 drawRect 更改为 drawRect2,或者如果我删除了整个方法,那么动画将起作用。

(可能还需要-drawRect,比如我们需要在自定义view FooView中画一个圆怎么办?)

这是为什么呢?除了提供一个解决方案,即使使用 -drawRect 也能使其正常工作,请解释是什么原因导致它没有动画?

最佳答案

drawRect: 的存在改变了 UIView 的操作方式。你应该只在绝对必要的时候使用 drawRect: 并且你永远不应该有一个空的 drawRect: 实现。

如果 -drawRect: 方法存在于您的子类中,那么 UIView 必须先做一些事情才能调用此方法。即,它必须分配一个可能很昂贵的后备存储,您的自定义绘图将出现在该后备存储中,并且它必须用背景颜色填充该后备存储。

然后 UIView 将调用您的 drawRect: 实现来对后备存储执行任何自定义绘图,然后再将后备存储交给 GPU。只有在所有这些之后,您的动画 block 才会开始运行。

因此在您的动画开始时,表示您的自定义 UIView 的后备存储已经被涂上了新的背景颜色。

如果您的 UIView 子类没有 drawRect: 方法,那么该 View 就没有后备存储。背景颜色由 GPU 直接处理,可以非常高效地动画化颜色之间的过渡。

空的 UIView 对象(没有 drawRect: 实现)相当轻量级。您的自定义 View 应该由多个 subview 组成,具体取决于您想要实现的动画效果。

例如,UITableViewCell 类由许多 subview 组成。 UITableViewCell 本身就是一个 UIView。它包含一个背景 View 和一个选定的背景 View 。最上面是内容 View ,内容 View 内部是各种文本标签和 ImageView 。所有这些 View 结合起来产生您在常规 UITableView 中看到的选择和调整大小动画。

关于iphone - 在 iOS 上,自定义 View 不会设置动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12454379/

相关文章:

objective-c - iOS - 放大 View (提供屏幕截图)

iphone - 用于我的 iPhone 应用程序的 Google Places API

iphone - 如何使用 CSS 在 iPhone 上最大化 webapp 高度? (正确隐藏 URL 栏)

ios - 重新启动并在 GameScene 中呈现

ios - 我怎样才能重新加载一个 imageView 与常量 chaged setAlpha?

ios - drawRect,绘制项目并忽略 mask

iphone - 设备旋转时更改 UIWindow 背景颜色

iphone - UIImageView 的框架和边界有什么区别?

ios - 支持 iOS 12 和 13 时的 AppDelegate 和 SceneDelegate

ios - 试图在其 super View 中居中 View