I am using UIInterpolatingMotionEffect to generate a "Shadow Effect" based on device tilt.
I have a label with some text and applying the following code to get the effect:
// Set shadow properties
let layer = self.label.layer
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowRadius = 9
layer.shadowOpacity = 0.7
layer.shadowOffset = CGSizeMake(10, 10)
// Set vertical shadow effect
let verticalMotionEffect: UIInterpolatingMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOffset.height", type: .TiltAlongVerticalAxis)
verticalMotionEffect.minimumRelativeValue = 100
verticalMotionEffect.maximumRelativeValue = -100
// Set horizontal shadow effect
let horizontalMotionEffect: UIInterpolatingMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOffset.width", type: .TiltAlongHorizontalAxis)
horizontalMotionEffect.minimumRelativeValue = 100
horizontalMotionEffect.maximumRelativeValue = -100
// Create group to combine both
let group = UIMotionEffectGroup()
group.motionEffects = [horizontalMotionEffect, verticalMotionEffect]
// Add both effects to the label
self.label.addMotionEffect(group)
The result is like this:

But I want the text to be invisible when the device is static or when the device is held parallel to the eyes. So one has to rotate / tilt the device to understand what is written.
The font colour is white. In the initial position the shadow should also be white or have 0 opacity and slowly increase the opacity as well as radius based on the device tilt.
I am unable to find a way to capture the device's tilt values, which I can then improvise with conditions to get my desired effect. All my web searches lead me to CMMotionManager. Is there a way to do this through UIInterpolatingMotionEffect or UIMotionEffect?
Thanks in advance!
By controlling the layer's shadow opacity, I was able to get the effect I was looking for. I am controlling the shadow opacity through both the tilt axis with a minimum and maximum value of -1.0 and 1.0 since I want the opacity to be 0 initially. Here is the code:
let layer = self.layer
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowRadius = radius
//layer.shadowOpacity = opacity
layer.shadowOffset = CGSizeMake(offset, offset)
// Set vertical shadow effect
let verticalMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOffset.height", type: .TiltAlongVerticalAxis)
verticalMotionEffect.minimumRelativeValue = -parallaxIntensity
verticalMotionEffect.maximumRelativeValue = parallaxIntensity
// Set vertical shadow opacity effect
let verticalTransparencyEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOpacity", type: .TiltAlongVerticalAxis)
verticalTransparencyEffect.minimumRelativeValue = -1.0
verticalTransparencyEffect.maximumRelativeValue = 1.0
// Set horizontal shadow effect
let horizontalMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOffset.width", type: .TiltAlongHorizontalAxis)
horizontalMotionEffect.minimumRelativeValue = -parallaxIntensity
horizontalMotionEffect.maximumRelativeValue = parallaxIntensity
// Set horizontal shadow opacity effect
let horizontalTransparencyEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOpacity", type: .TiltAlongHorizontalAxis)
horizontalTransparencyEffect.minimumRelativeValue = -1.0
horizontalTransparencyEffect.maximumRelativeValue = 1.0
// Create group to combine all effects
let group = UIMotionEffectGroup()
group.motionEffects = [verticalMotionEffect, verticalTransparencyEffect, horizontalMotionEffect, horizontalTransparencyEffect]
// Add both effects to the label
self.addMotionEffect(group)
NOTE: Manual setting of layer.shadowOpacity needs to be disabled for it to work.
The idea of the UIInterpolatingMotionEffect is to take care for itself - you just provide the minimum and maximum values and it reads the axis values and translates the tilt value (in the range of -1 to 1) to a value relative to you minimum and maximum ones. It is not intended for directly providing you the tilt value.
A possible "hack", which I do not recommend is to create a transparent view, with min value of -1 and max value of 1. This way you can read the tilt value from this view.
EDIT: You can check this answer Use UIMotionEffect with OpenGL ES which explains a similar approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With