Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving an image with ios 7 parallax effect

Tags:

ios

facebook

ios7

I just saw Facebook's new paper app that makes images move based on the parallax effect. So it zoom's the image to full screen and when you tilt the screen, it scrolls the image to the side you tilted. I have been able to add the parallax effect like apple has it, but not like how facebook has it. Does anyone have any ideas how they did this. Here is the basic code I was using for parallax:

UIInterpolatingMotionEffect *interpolationHorizontal = [[UIInterpolatingMotionEffect alloc]initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
interpolationHorizontal.minimumRelativeValue = @-10.0;
interpolationHorizontal.maximumRelativeValue = @10.0;

UIInterpolatingMotionEffect *interpolationVertical = [[UIInterpolatingMotionEffect alloc]initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
interpolationVertical.minimumRelativeValue = @-10.0;
interpolationVertical.maximumRelativeValue = @10.0;

[self.backgroundView addMotionEffect:interpolationHorizontal];
[self.backgroundView addMotionEffect:interpolationVertical];
like image 493
matthew Avatar asked Feb 04 '14 05:02

matthew


Video Answer


1 Answers

Update: Just found a very nice 3rd party library for achieving this, it's called CRMotionView, it works very smooth and you can modify a lot of things.

here is the github link: https://github.com/chroman/CRMotionView

==================================================================================

i was thinking the same parallax when i first saw Facebook paper app. but after play with my code for a little bit, i don't think parallax is what we looking for. I could be wrong, but i went to do it all from the base, gyro motion manager. Here is my sample code:

     //import the motion manager frame work first
     #import <CoreMotion/CoreMotion.h>

     //then need to add a motionManager
     @property (strong, nonatomic) CMMotionManager *motionManager;

    //you can paste all those codes in view did load
    //i added a scroll view on the view controller nib file
    self.mainScrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    //we don't want it to bounce at each end of the image
    self.mainScrollView.bounces = NO;

    //and we don't want to allow user scrolling in this case
    self.mainScrollView.userInteractionEnabled = NO;

    //set up the image view
    UIImage *image= [UIImage imageNamed:@"YOUR_IMAGE_NAME"];
    UIImageView *movingImageView = [[UIImageView alloc]initWithImage:image];
    [self.mainScrollView addSubview:movingImageView];

    //set up the content size based on the image size
    //in facebook paper case, vertical rotation doesn't do anything
    //so we dont have to set up the content size height
    self.mainScrollView.contentSize = CGSizeMake(movingImageView.frame.size.width, self.mainScrollView.frame.size.height);

    //center the image at intial
    self.mainScrollView.contentOffset = CGPointMake((self.mainScrollView.contentSize.width - self.view.frame.size.width) / 2, 0);

    //inital the motionManager and detec the Gyroscrope for every 1/60 second
    //the interval may not need to be that fast
    self.motionManager = [[CMMotionManager alloc] init];
    self.motionManager.gyroUpdateInterval = 1/60;

    //this is how fast the image should move when rotate the device, the larger the number, the less the roation required.
    CGFloat motionMovingRate = 4;

    //get the max and min offset x value
    int maxXOffset = self.mainScrollView.contentSize.width - self.mainScrollView.frame.size.width;
    int minXOffset = 0;

    [self.motionManager startGyroUpdatesToQueue:[NSOperationQueue currentQueue]
                                withHandler:^(CMGyroData *gyroData, NSError *error) {
         //since our hands are not prefectly steady
         //so it will always have small rotation rate between 0.01 - 0.05
         //i am ignoring if the rotation rate is less then 0.1
         //if you want this to be more sensitive, lower the value here
         if (fabs(gyroData.rotationRate.y) >= 0.1) {
            CGFloat targetX = self.mainScrollView.contentOffset.x - gyroData.rotationRate.y * motionMovingRate;
             //check if the target x is less than min or larger than max
             //if do, use min or max
             if(targetX > maxXOffset)
                   targetX = maxXOffset;
             else if (targetX < minXOffset)
                   targetX = minXOffset;

             //set up the content off
             self.mainScrollView.contentOffset = CGPointMake(targetX, 0);
          }
   }];

I tested this on my device, worked pretty similar like facebook new app.

However, this is just an example code i wrote in half hour, may not be 100% accurate, but hope this would give you some ideas.

like image 196
Xu Yin Avatar answered Oct 26 '22 12:10

Xu Yin