The Finnternet Like the Internet but with more me

Get Swifty: Accelerometer & Parallax Images

Accelerometers are one of the mobile features that might not get that much use but when it does, it usually gives cool results as you can see in the gif of the Parallax image example that we will cover below.

Input Accessory View

Using the accelerometers in iOS only takes four steps,

  • import Coremotion, the iOS framework for handling the accelerometer, gyroscope, pedometer, and environment-related events.
  • declare & initialize a CMMotionManager
  • create a function that you want to be called with the accelerometer updates
  • start listening for accelerometer updates

These steps can be seen implemented in the ViewController below

import CoreMotion

class ViewController: UIViewController {
    
    var motionManager: CMMotionManager!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        motionManager = CMMotionManager()
        motionManager.startAccelerometerUpdates(to: .main, withHandler: readAccelerometer)
    }
    
    func readAccelerometer(data: CMAccelerometerData?, error: Error?) {
        guard let accelerometerData = data else { return }
        
        // Access accelerometer data
        // X: accelerometerData.acceleration.x
        // Y: accelerometerData.acceleration.y
        // Z: accelerometerData.acceleration.z
    }
} 

Parallax

Now for one of my favorite uses of the accelerometer input, Parallax images. I remember when I first noticed the subtle effect on the iOS homescreen I found it so cool. Although this could be done using the accelerometer input above, iOS provides us with a simpler way using UIInterpolatingMotionEffect.

All you have to do is,

  • create a UIInterpolatingMotionEffect, specifying the property (keypath) you want to link the motion to and the type of motion you are interested in
  • set the min & max movement amounts allowed
  • create a UIMotionEffectGroup & set its motionEffectsapply to the UIInterpolatingMotionEffects you created
  • apply the motionEffectGroup to your view using addMotionEffect(UIMotionEffectGroup)

Here is a simple UIImageView extension that you can use to add the Parallax effect to any UIImageView by calling myImageView.parallax(). I should also note that to avoid seeing the background, you should set the UIImageView’s Content Mode to “Center”.

extension UIImageView {
    func parallax() {
        let min = CGFloat(-30)
        let max = CGFloat(30)
        
        let xMotion = UIInterpolatingMotionEffect(keyPath: "layer.transform.translation.x", type: .tiltAlongHorizontalAxis)
        xMotion.minimumRelativeValue = min
        xMotion.maximumRelativeValue = max
        
        let yMotion = UIInterpolatingMotionEffect(keyPath: "layer.transform.translation.y", type: .tiltAlongVerticalAxis)
        yMotion.minimumRelativeValue = min
        yMotion.maximumRelativeValue = max
        
        let motionEffectGroup = UIMotionEffectGroup()
        motionEffectGroup.motionEffects = [xMotion, yMotion]
        
        self.addMotionEffect(motionEffectGroup)
    }
}