UIView setCenter 的替代品
Posted
技术标签:
【中文标题】UIView setCenter 的替代品【英文标题】:alternative to UIView setCenter 【发布时间】:2014-04-18 03:06:30 【问题描述】:我的应用程序是一款游戏,它包含一个 CADisplayLink
计时器,该计时器调用一个函数,该函数指示每帧屏幕上的各种对象对 UIView setCenter:
进行大约 20 次调用。
时间分析,这约占游戏中所有活动的 30%,并大大降低了旧设备(低于第 5 代 ipod touch 或 iphone)的性能。
我可以使用任何轻量级、低开销的替代方案来每帧在屏幕上移动对象(特别是 UIViews
)吗?
编辑:
澄清一下,这些UIViews
的center
属性必须在每一帧中设置。我的游戏中有许多代表地面的图块。它们在屏幕上滑动,只是被新的瓷砖取代。在摆弄代码几个小时以将UIView
s 更改为CAlayer
s 之后,我让它完全没有性能提升。肯定有更好的方法来做到这一点。
一些代码可以大致了解正在发生的事情:
for(Object* o in gameController.entities)
[o step:curTimeMS];
gameController
,正如人们所想的那样,是一个负责主要游戏功能的类。它包括其实体列表,即屏幕上的所有对象。每个实体上的 step
方法是一个虚函数,因此它特定于每个实体 - curTimeMS
变量只是一个时间戳,因此对象可以计算其增量位置。实质上,每个实体每帧都会更新其layer.position
属性,并以适当的速度在屏幕上移动。
【问题讨论】:
既然是游戏,你检查过SpriteKit了吗?这是一个很棒的框架,有趣且易于使用。 @Winston 同意,但我认为他想在早期的系统上运行。 是的,没错,因为他在他的问题上提到了第 5 代 ipod touch 或 iPhone。 @Winston 正如马特所说,我确实想支持早期的系统,但 SpriteKit 似乎是未来的好方法,感谢您的建议:) 你会玩得很开心的。 【参考方案1】:我会推荐 SpriteKit。这是一个very powerful game / 2d animation framework created by apple.。 Cocos2D is also a very powerful framework of similar type. 你可以直接从XC创建一个新的SpriteKit游戏
如果您想留在家里只带UIKit
的东西,请查看UIView block based animations
。这是它的要点。
[UIView animateWithDuration:numberOfSecondsTakenToAnimate animations: ^
// do you animation here. i.e.: move view frame, adjust color.
completions: ^(BOOL complete)
// when the animation is complete, code in this block is executed.
];
我只记得Core Graphics。它与UIView
s 一起使用来创建简单的2d 图形,并且非常 强大且非常 快速。这是其中的要点。
CGContextRef cntxt = UIGraphicsGetCurrentContext();
CGContextBeginPath(cntxt);
CGContextMoveToPoint(cntxt, <x>, <y>);
CGContextAddLineToPoint(cntxt, <x>, <y>);
CGContextClosePath(cntxt);
[[UIColor <color>] setFill];
[[UIColor <color>] setStroke];
CGContextDrawPath(cntxt, kCGPathFillStroke);
注意:中的东西是你指定的变量/值。
如果你想全力以赴,take the time to learn Open GL。请注意,我听说这非常难学。
【讨论】:
感谢您的回答。但是,正如之前的 cmets 中所讨论的,我故意不使用 SpriteKit 以支持早期的 iOS 版本和设备。 我知道UIView
的animateWithDuration: animations:
,但我没有考虑将它作为框架调整的基础。您认为这会带来性能提升吗?
@Fitzy 不确定,但它看起来非常流畅。如果您正在寻找性能,还可以查看我对 Core Graphics 的编辑。我对这个框架有个人经验,我可以证明它的性能
我刚刚看到你的编辑,似乎有些人建议使用它,而我在这个网站上看到的其他答案明确表示 Core Graphics 和 UIKit 之间的差异可以忽略不计,因为 UIKit 的 @987654334 @ 是 CALayer
的一个非常轻量级的包装器
好吧,我相信你。我会研究选项。至于 OpenGL,我对它有一定的经验,并且可以确认它对于这个小 2D 游戏来说绝对是矫枉过正。 :)【参考方案2】:
如果您需要性能,请不要使用UIView
。它的设计初衷不是为了快速。
相反,有一个 UIView
占据整个屏幕,在一个视图内有一堆 CALayer
对象。移动图层。
CALayer
通过直接与 GPU 对话来工作,因此速度非常快。也许甚至比 OpenGL 还要快。 UIView
在内部使用 CALayer
,因此它们的行为大致相同。唯一真正的区别是对CALayer
位置的任何更改将默认设置为动画。您可以轻松关闭动画,但在游戏中您可能需要动画。
当然,您的另一个选择是使用 OpenGL。但这还有很多工作要做。
编辑:这里是一些用于正确更改图层位置的示例代码:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/CreatingBasicAnimations/CreatingBasicAnimations.html#//apple_ref/doc/uid/TP40004514-CH3-SW8
【讨论】:
我在其他 SO 答案中读到CALayer
和 UIView
没有任何显着的性能差异。所以值得改变我的代码来支持CALayers
而不是UIView
s?我确实有使用 OpenGL 的经验,但是由于这个项目即将完成,最好不要重写大量代码。
我可以在重组一堆代码后确认CALayer
对性能没有任何改进,并且在时间配置文件中进行测试时,所有相同的底层函数都会被调用。
@Fitzy 所以您发现将图层从屏幕上的一个位置移动到另一个位置很慢?而你只有20层?这根本不是我的经验,我的代码可以一次移动 200,000 层或更多层而没有性能问题。您可以发布您正在使用的代码吗?
@Fitzy 我更新了我的答案以显示 Apple 如何建议您应该沿特定路径移动图层的位置。请注意,他们不使用setPosition:
。但是,我个人对setPosition:
的使用要求很高,没有性能问题。我想再看看你的代码。以上是关于UIView setCenter 的替代品的主要内容,如果未能解决你的问题,请参考以下文章
两个 UIView,一个 UIViewController(在一个 UINavigationController 中)