Question

I have a series of images within a ViewController.

I am "floating" them by transforming their individual layers:

img.layer.transform = CATransform3DMakeTranslation(0.0f, 0.0f, myZ);

This gives the effect of making the layers float above the screen -- in the Simulator, there would be no visible effect (which is correct).

What I want to do is have an effect where moving a device left/right/forward/or back would make it look subtly like the layers are floating. When you tilt the device to the left, it should angle the entire view to the right. This will make it feel like moving the device lets you see around corners -- i.e. it will give a feeling that the images really are floating above the screen, because they would move at different rates (based on their z-index).

I have made a test project (project file here) which has a sample project that demos this.

My problem is that I am not a math person, so I am struggling with the best way to simulate the subtle floating effect. Right now, I've got a listener for DeviceMotion, which then does:

self.view.layer.sublayerTransform = CATransform3DMakeRotation(20.0f * M_PI / 180.0f, 2*motion.attitude.pitch, -2*motion.attitude.roll, 0);

This is very close to what I want, but it's not exactly right.

I think this effect will be something that could be used in a number of different applications. I am hoping to extend this to something a friend and I are working on with face detection (so it would move the parent view based on the movement of a person's face -- even while they keep the phone/device perfectly still).

I realize I will get people answering "just use OpenGL". That's not the answer I need -- unless you post a chunk of code that shows how to integrate it within this project. (I'm not looking for new problems to solve. :-)

Again, the full project is here (iphone floating views) for anyone who would like to see the effect as it is right now. (When this is working, I will leave the full (working) project linked here for posterity.)

Was it helpful?

Solution

I think I've got this! Use this:

    [appDelegate.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
                                                   withHandler:
     ^(CMDeviceMotion *motion, NSError *error) {

         CATransform3D transform;
         transform = CATransform3DMakeRotation(motion.attitude.pitch, 1, 0, 0);
         transform = CATransform3DRotate(transform, motion.attitude.roll, 0, 1, 0);

         self.view.layer.sublayerTransform = transform;
     }];

Works like charm for me, if you want to flip axes, just add minus sign in front of those 1s.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top