Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@maciekish
Last active April 14, 2019 18:08
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save maciekish/ecb670b9398d47bdf196 to your computer and use it in GitHub Desktop.
Save maciekish/ecb670b9398d47bdf196 to your computer and use it in GitHub Desktop.
Easy UIInterpolatingMotionEffect. Learn more: http://hack.swic.name/easy-uiinterpolatingmotioneffect
//
// NaturalMotion.swift
//
// Created by Maciej Swic on 2014-06-06.
// Released under the MIT license.
//
import UIKit
extension UIView {
func addNaturalOnTopEffect(maximumRelativeValue : Float = 20.0) {
//Horizontal motion
var motionEffect = UIInterpolatingMotionEffect(keyPath: "center.x", type: .TiltAlongHorizontalAxis);
motionEffect.minimumRelativeValue = maximumRelativeValue;
motionEffect.maximumRelativeValue = -maximumRelativeValue;
addMotionEffect(motionEffect);
//Vertical motion
motionEffect = UIInterpolatingMotionEffect(keyPath: "center.y", type: .TiltAlongVerticalAxis);
motionEffect.minimumRelativeValue = maximumRelativeValue;
motionEffect.maximumRelativeValue = -maximumRelativeValue;
addMotionEffect(motionEffect);
}
func addNaturalBelowEffect(maximumRelativeValue : Float = 20.0) {
addNaturalOnTopEffect(maximumRelativeValue: -maximumRelativeValue)
}
}
//
// UIView+NaturalMotion.h
//
// Created by Maciej Swic on 30/04/14.
// Released under the MIT license.
//
#import <UIKit/UIKit.h>
@interface UIView (NaturalMotion)
+ (void)addNaturalOnTopEffectWithMaximumRelativeValue:(CGFloat)maximumRealtiveValue;
+ (void)addNaturalBelowEffectWithMaximumRelativeValue:(CGFloat)maximumRealtiveValue;
@end
//
// UIView+NaturalMotion.m
//
// Created by Maciej Swic on 30/04/14.
// Released under the MIT license.
//
#import "UIView+NaturalMotion.h"
@implementation UIView (NaturalMotion)
+ (void)addNaturalOnTopEffectWithMaximumRelativeValue:(CGFloat)maximumRealtiveValue {
UIInterpolatingMotionEffect* motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
motionEffect.minimumRelativeValue = @(maximumRealtiveValue);
motionEffect.maximumRelativeValue = @(-maximumRealtiveValue);
[self addMotionEffect:motionEffect];
motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
motionEffect.minimumRelativeValue = @(maximumRealtiveValue);
motionEffect.maximumRelativeValue = @(-maximumRealtiveValue);
[self addMotionEffect:motionEffect];
}
+ (void)addNaturalBelowEffectWithMaximumRelativeValue:(CGFloat)maximumRealtiveValue {
UIInterpolatingMotionEffect* motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
motionEffect.minimumRelativeValue = @(-maximumRealtiveValue);
motionEffect.maximumRelativeValue = @(maximumRealtiveValue);
[self addMotionEffect:motionEffect];
motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
motionEffect.minimumRelativeValue = @(-maximumRealtiveValue);
motionEffect.maximumRelativeValue = @(maximumRealtiveValue);
[self addMotionEffect:motionEffect];
}
@end
@smileyborg
Copy link

Why not just make this a category on UIView? That would reduce the API down to something like:

@interface UIView (NaturalMotion)

- (void)addNaturalMotionEffectAboveWithMaximumRelativeValue:(CGFloat)maximumRelativeValue;
- (void)addNaturalMotionEffectBelowWithMaximumRelativeValue:(CGFloat)maximumRelativeValue;

@end

@maciekish
Copy link
Author

Good idea! I also added a Swift version.

@khoogheem
Copy link

Remove Effects-

func removeMotionEffects() {
    let motionEffects = self.motionEffects as [UIMotionEffect]
    for effect in motionEffects {
        self.removeMotionEffect(effect)
    }
}
- (void)removeMotionEffects {
    NSArray *motionEffects = [NSArray arrayWithArray:self.motionEffects];
    [motionEffects enumerateObjectsUsingBlock:^(UIMotionEffect *motionEffect, NSUInteger idx, BOOL *stop) {
        [self removeMotionEffect:motionEffect];
    }];

}

@adamcian
Copy link

Should group the horizontal and vertical effects into a UIMotionEffectGroup for performance so they are evaluated at the same time.

@jowie
Copy link

jowie commented Aug 8, 2016

Left-right and top-bottom are inverted. The image should move from right-to-left if in the background.

@revolter
Copy link

Typo: realtive instead of relative.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment