Iphone – Stacked UIView Layers Don’t Move


I'm developing an iPhone app that moves a UIView layer between other UIView layers based upon the accelerometer.

If the topmost layer is the one that's moving based upon the accelerometer, no problem. If I add a UIView on top of it, the movement is extremely delayed. If I add a second UIView on top of it, the movement stops.

The updateInterval is 60, and I'm using UIView's drawAtPoint: method to move the layer.

My question: is there a UIView property, such as opaque, clipsToBounds, etc. that needs to be enabled for accurate accelerometer based movement of a sandwiched UIView to occur?

Thanks in advance for any assistance you can provide.


The bottom layer is opaque and the layers above are transparent PNGs.

I'm having difficulty accessing the frame property of a UIView. Here's some of the code from my Object2D class:

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

And here's the class' original draw: method that is called from the ViewController class:

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

I've tried various ways to access the frame property, to no avail:

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

Looking in the API docs suggest that the first way will work but it doesn't.

Do you know how to access the frame property of a UIView?

Thanks in advance.

Best Solution

You can't set individual frame parameters directly. You must create a new CGRect and set the frame to that CGRect. There are different ways to change the parameters of a CGRect once you have created it.

CGRect myNewFrame = someView.frame;

myNewFrame.origin.x = 1.0;

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

someView.frame = myNewFrame;

The idea is to set the CGRect how you want it and then set the view's frame property to that CGRect, then your good.

As far as the UIView... You may have a few problems. First, as said above the drawAtPoint method is expensive. Second, and maybe worse, you have several transparent images. Transparency is one of the most expensive operations on the iPhone, in fact, there is a test in Instruments just for that. You should avoid transparency at all costs. A few transparent PNGs with a redraw all during rotation will most likely give you app hiccups.

My next advice would be to consider if you need the View in the middle of the transparencies, maybe another layer could do the job. if you need touch functionality, you can use the view at the root of the layer hierarchy to handle touches. In other words from back to front you have this:
UIView CALayer UIView CALayer CALayer

but you could just have this: UIView (now handle all touches) CALayer CALayer (previously a view) CALayer CALayer

This will also help as CALayers have less overhead than UIViews.

Hope this helps.