Iphone 如何强制视图渲染自身?

Iphone 如何强制视图渲染自身?,iphone,ios,Iphone,Ios,在我的应用程序中,我有许多小的子视图。当用户点击一个子视图时,我将一个单独的视图放置在点击的子视图(相同大小)的顶部,然后将这个单独的视图设置为全屏大小 放大视图是自定义绘制的,这给这种方法带来了一个大问题。如果在主视图的viewDidLoad方法中创建放大视图,并将其帧设置为全屏大小,则会立即调用视图的drawRect方法,并正确渲染视图的全尺寸。如果我在动画中使用此视图,则一切都会按预期进行 但是,我需要根据点击的子视图的不同,此放大视图有所不同,因此每次都需要重新创建/重新绘制它。问题是,

在我的应用程序中,我有许多小的子视图。当用户点击一个子视图时,我将一个单独的视图放置在点击的子视图(相同大小)的顶部,然后将这个单独的视图设置为全屏大小

放大视图是自定义绘制的,这给这种方法带来了一个大问题。如果在主视图的
viewDidLoad
方法中创建放大视图,并将其帧设置为全屏大小,则会立即调用视图的
drawRect
方法,并正确渲染视图的全尺寸。如果我在动画中使用此视图,则一切都会按预期进行

但是,我需要根据点击的子视图的不同,此放大视图有所不同,因此每次都需要重新创建/重新绘制它。问题是,当我响应触摸事件执行此操作时,视图的
drawRect
方法在动画开始之前不会被调用,此时视图的帧很小,而不是全屏,因此所有内容都绘制错误

在我的触摸事件代码中,我显式地将视图的帧设置为全屏,并在开始动画之前调用
setNeedsDisplay
,但这没有效果-
drawRect
只是在动画开始之前才被调用


有没有办法强制重画,以便在视图的边框为我希望的大小时绘制视图?

调用
setNeedsDisplay
后,可能需要一些时间才能调用drawRect。以短(0.1f)延迟开始动画。您还可以从[self-performSelector:withObject:afterDelay:]调用动画方法来添加延迟,如果这更容易的话。

正如我上面所评论的,Joe问了一些类似的问题(作为一个更一般的问题),Tom Swift处理当前运行循环

他的建议是在调用
-setNeedsDisplay
后立即使用以下代码强制运行循环进行一次迭代:

[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];
这种方法有一些注意事项,在那里的评论中讨论过

还有人指出

[CATransaction flush];

也可能达到强制立即重画视图的效果。

正确的方法是简单地划分方法


只需调用
setNeedsDisplay
,然后返回而不设置动画。等待正确设置所有内容的
drawRect
完成其重画,然后让它排队等待另一个启动所需动画的方法(通过排队操作或通知)。然后开始动画。这一切都可以相当快地发生(以帧速率),并且不涉及额外的(危险的)递归运行循环调用或CATTransaction调用(这可能会导致额外的GPU设置)。

一位苹果工程师提供了另一种推荐的解决方案。使用2个UIView,一个小视图和一个大视图,大视图的alpha为0。渲染二者,将大画面的帧设置为小画面,并使动画交叉淡入淡出,以及将两个尺寸从小变大。

我相信Joe在他的问题中提出了类似的问题,这可能会实现您的目标。@Brad:这很好,谢谢。如果你把你的评论作为一个实际的答案,我会选择它。这是有效的代码行:
[[NSRunLoop currentRunLoop]运行模式:NSDefaultRunLoopMode beforeDate:[NSDate date]]很高兴它起作用了。我之所以发表评论,是因为我不太确定我是否理解您的需求,因为何时需要进行重画。另外,
[CATransaction flush]
可以执行您想要的操作,而无需您操纵运行循环。但是,在触发动画之前,您可能会想使用它,因为它可能会干扰动画。@Joe:如果您能在我的iPhone出现问题时多做些努力来回答这些问题,我可能真的可以回到我的音乐软件了。:)在setNeedsDisplay之后调用[CatTransaction flush]对我来说也适用于类似的情况。我确实尝试过这样做,但由于视图以0.0的alpha值开始动画,因此无论我在开始动画之前等待多长时间-
drawRect
都不会被调用,直到动画真正开始。操作系统基本上是在说“在我不得不之前我不会渲染这个东西”,这是有道理的。我认为这行不通。我的问题本质上是,我正在尝试将视图从非常小的屏幕设置为全屏,但我需要确保它最初是全尺寸渲染的(通过drawRect),以便它在全尺寸下看起来最好。我能让视图自身呈现全尺寸的唯一方法是使用Brad答案中的两种方法之一,而不是在屏幕上实际显示视图,我在动画结束前不想这样做。