堆叠的UIView图层不要移动

时间:2009-01-16 21:19:39

标签: iphone cocoa-touch

我正在开发一款iPhone应用程序,可根据加速度计在其他UIView图层之间移动UIView图层。

如果最顶层是基于加速度计移动的层,没问题。如果我在它上面添加一个UIView,则运动极度延迟。如果我在它上面添加第二个UIView,则移动停止。

updateInterval是60,我正在使用UIView的drawAtPoint:方法来移动图层。

我的问题:是否有一个UIView属性,例如opaque,clipsToBounds等,需要启用才能实现基于加速计的夹心UIView运动?

提前感谢您提供的任何帮助。

更新

底层是不透明的,上面的层是透明的PNG。

我无法访问UIView的frame属性。以下是我Object2D类的一些代码:

- (id)initWithImage:(NSString*)imageName
{
    if (self = [super init])
    {
        position = [[Point2D alloc] init];
        vector = [[Vector2D alloc] init];
        imagePath = [[NSBundle mainBundle] pathForResource:imageName ofType:@"png"]; 
        myImageObj = [[UIImage alloc] initWithContentsOfFile:imagePath]; 
        size.width = myImageObj.size.width;
        size.height = myImageObj.size.height;
    }

    return self;
}

这是从draw:类调用的类'原始ViewController方法:

- (void)draw
{
    [myImageObj drawAtPoint:CGPointMake( position.X, position.Y ) ];
    [ self setNeedsDisplay ];
}

我尝试了各种方法来访问frame属性,但无济于事:

myImageObj.frame = CGRectMake(position.X, position.Y, size.width, size.height);
myImageObj.CGImage.frame.y = position.Y;

查看API文档表明第一种方法可行,但事实并非如此。

您知道如何访问UIView的frame属性吗?

提前致谢。

3 个答案:

答案 0 :(得分:4)

您无法直接设置单个帧参数。您必须创建一个新的CGRect并将框架设置为该CGRect。创建CGRect后,有多种方法可以更改CGRect的参数。

CGRect myNewFrame = someView.frame;

myNewFrame.origin.x = 1.0;

myNewFrame.size = CGSizeMake(100.0f, 50.0f);

someView.frame = myNewFrame;

我的想法是设置CGRect你想要的方式,然后将视图的frame属性设置为CGRect,然后是你的好。

至于UIView ...... 你可能有一些问题。首先,如上所述,drawAtPoint方法很昂贵。其次,也许更糟糕的是,你有几个透明的图像。透明度是iPhone上最昂贵的操作之一,事实上,仪器中只有一个测试。你应该不惜一切代价避免透明度。一些透明的PNG在旋转过程中全部重绘,很可能会给你带来应用程序打嗝。

我的下一个建议是考虑是否需要透明胶片中间的视图,也许另一层可以完成这项工作。如果需要触摸功能,可以使用图层层次结构根目录中的视图来处理触摸。换句话说,从后到前你有这个:
的UIView CALayer的 的UIView CALayer的 CALayer的

但你可以这样: UIView(现在处理所有接触) CALayer的 CALayer(以前的观点) CALayer的 CALayer的

这也有助于CALayers的开销低于UIViews。

希望这有帮助。

答案 1 :(得分:2)

每次使用drawAtPoint时:都会强制将UIView重新渲染到图形层中。这很贵。

UIView已经有了一个-frame属性来定义它的位置和大小。仅更新位置允许图形硬件移动已经合成的图层。

我不确定“夹心”是什么意思,但我假设它将图层放在不同的z索引上?如果是这样,我假设中间(你正在移动的层)和顶层必须是透明的,底层应该是不透明的以便具有高效性。

请告诉我这不是你想要的......

答案 2 :(得分:1)

我认为你误解了UIViews是如何工作的。首先,您要创建UIImageViews来托管您的UIImages。然后,您希望使用其addSubview:方法将它们添加到一个superview。最后,您想要更改中间UIImageView的frame属性(如果您希望它平滑地动画,则在beginAnimations / commitAnimations块中)以使其移动到新位置。

如果将UIImage放在封装的UIImageView中,它将作为纹理缓存在GPU上,并且UIImageView位置的任何变化都将是硬件加速的。 drawAtPoint:正如Dan指出的那样,非常昂贵,如果可以,应该避免。你的myImageObj.frame = CGRectMake代码正确,你需要应用于UIImageView,而不是UIImage。

对于简单的三层结构,除非您有大量图像,否则即使是具有大量透明度的图像也会平滑地生成动画。我已经为数十个透明的UIViews(它们只是CALayers周围非常轻的包装器)做了这个,没有性能障碍。

顺便说一句,如果您的Point2D和Vector2D类只是二维坐标的包装器,您可能需要考虑用CGPoint结构替换它们。围绕该轻量级数据类型有很多支持函数。