2

I'm trying to apply a UIMotionEffect to a custom property on a GLKView subclass. This is my code on the view's setup:

UIInterpolatingMotionEffect *horizontalMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"customCenter.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];    
horizontalMotionEffect.minimumRelativeValue = @(-50);
horizontalMotionEffect.maximumRelativeValue = @(50);
[self addMotionEffect:horizontalMotionEffect];

The property is defined as:

@property (nonatomic) CGPoint customCenter;

But when I log the property in the animation loop its alwas 0. What am I missing?

Odrakir
  • 4,254
  • 1
  • 20
  • 52
  • Check out this amazing example ... http://rogchap.com/2013/08/23/custom-uiview-animations-with-vector-graphics/ And note answers like http://stackoverflow.com/a/2396461/294884 – Fattie May 02 '16 at 23:10

1 Answers1

3

I was looking for an answer to this and found a solution by myself.

I wanted to animate an SCNNode, but it should be easily done for any other custom object.

I made a subclass of UIMotionEffect and override keyPathsAndRelativeValuesForViewerOffset(viewerOffset: UIOffset) -> [String : AnyObject]?. My subclass is initialized with a SCNNode so it can modify its properties when tilting the phone. That way you can animate non-animatable properties.
Here is my swift code:

class SCNNodeTiltMotionEffect: UIMotionEffect {

    var node: SCNNode? // The object you want to tilt
    var baseOrientation = SCNVector3Zero
    var verticalAngle = CGFloat(M_PI) / 4
    var horizontalAngle = CGFloat(M_PI) / 4

    init(node: SCNNode) {
        super.init()
        self.node = node // Set value at init
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func keyPathsAndRelativeValuesForViewerOffset(viewerOffset: UIOffset) -> [String : AnyObject]? {
        // Set any properties of your object with values of viewerOffset attributes
        node?.eulerAngles = SCNVector3Make(baseOrientation.x, baseOrientation.y + Float(viewerOffset.horizontal * horizontalAngle), baseOrientation.z - Float(viewerOffset.vertical * verticalAngle))
        return nil
    }
}

If you want to animate animatable properties, you should return a dictionary with keypaths and values or use UIInterpolatingMotionEffect, more details in the official documentation

Crazyrems
  • 2,551
  • 22
  • 40