iOS 9 Swift Programming Cookbook (2015)
Chapter 13. UI Dynamics
13.4 Adding Animated Noise Effects to Your UI
Problem
You want to add a noise field on your UI and have your UI components surf in all directions on this field.
Solution
1. Create a noise field using the noiseFieldWithSmoothness(_:animationSpeed:) class method of UIFieldBehavior.
2. Add the views you want affected by this noise to the field using its addItem(_:) method.
3. Add your noise field to an animator of type UIDynamicAnimator (see Recipe 13.1).
NOTE
This recipe is based on what you learned in Recipe 13.1, so I won’t be going through all the details that I have already explained.
Discussion
Noise is great for having an item constantly move around on your reference view in random directions. Have a look at the noise field in Figure 13-5. This noise field is shown graphically on our UI using a UI Dynamics debugging trick (see Recipe 13.1).
Figure 13-5. Noise field affecting a square view
The direction of the noise that you see on the fields dictates in which direction the field repels the items attached to it. In this case, I’ve used negative gravity (think of it that way). If you want to limit the effective region of your noise field on your reference view, simply set the regionproperty of your field. This is of type UIRegion.
Now create your UI exactly as you did in Recipe 13.1. You should have an orange view that is accessible through the orangeView property of our view controller. Create a collision detector and an animator using what you learned in the aforementioned recipe. Now go ahead and create your noise field:
lazy var noise: UIFieldBehavior = {
let noise = UIFieldBehavior.noiseFieldWithSmoothness(0.9,
animationSpeed: 1)
noise.addItem(self.orangeView)
return noise
}()
Add the noise field to your animator:
override func viewDidLoad() {
super.viewDidLoad()
animator.addBehavior(collision)
animator.addBehavior(noise)
}
Last but not least, handle your pan gesture recognizer’s event, so that when the user starts dragging the orange view across the screen, your dynamic behaviors will shut down. And as soon as the user is done with dragging, they will come back up:
@IBAction func panning(sender: UIPanGestureRecognizer) {
switch sender.state{
case .Began:
collision.removeItem(orangeView)
noise.removeItem(orangeView)
case .Changed:
orangeView.center = sender.locationInView(view)
case .Ended, .Cancelled:
collision.addItem(orangeView)
noise.addItem(orangeView)
default: ()
}
}
See Also