iosswiftuidynamicanimatoruigravitybehavior

Slider determines gravity


So far I've created a rectangle that starts from the bottom and moves upward using UiDynamicAnimator. I would like the user to determine the "strength" of the negative gravity. I want the user to determine the value through a slider.

This is my code so far:

    import UIKit

class ViewController: UIViewController {

    var orangeSquare: UIView?
    var animator: UIDynamicAnimator?

    override func viewDidLoad() {
        super.viewDidLoad()


        func sliderChanged(sender: AnyObject) {

            var sliderValue = sender.value

        }

                //Create animation
            let dim = CGRectMake(100, 500, 200, 100)
            orangeSquare = UIView(frame: dim)
            orangeSquare?.backgroundColor = UIColor.orangeColor()

                //Add item to the screen
            self.view.addSubview(orangeSquare!)

                //Initialize the animator
            animator = UIDynamicAnimator(referenceView: self.view)

                //Add gravity
            let gravity = UIGravityBehavior(items: [orangeSquare!])
            let direction = CGVectorMake(0.0, sliderValue)
            gravity.gravityDirection = direction

                //Collision
            let boundries = UICollisionBehavior(items: [orangeSquare!])
            boundries.translatesReferenceBoundsIntoBoundary = true

                //Add animations
            animator?.addBehavior(boundries)
            animator?.addBehavior(gravity)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

I get two errors:

"Ambiguous use of ´value´" and "Use of unresolved identifier ´sliderValue´"

How do I convert ´sliderValue´ into a float with just one decimal point?


Solution

  • your code is missing a few things. sliderValue is an unresolved identifier because you have only declared it within sliderChanged but are referring to it in the main body of viewDidLoad. Also, I think that your use of value is ambiguous because you have declared the parameter to the function as AnyObject, whose value could be any one of a number of things!

    Your code was missing a mechanism linking a change in the value of the slider with a change in the gravity behaviour. As such, I've implemented this using an explicit target attached to the slider object. I've also thrown in a label showing the magnitude of the gravitational force. This is quite rough but I think it achieves what you were looking to do.

    import UIKit
    
    class ViewController: UIViewController {
    
        var dynamicAnimator : UIDynamicAnimator!
        var gravityBehaviour : UIGravityBehavior!
        var orangeSquare : UIView!
        var slider : UISlider!
        var sliderLabel : UILabel!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Subviews
            self.orangeSquare = {
                let oS : UIView = UIView(frame: CGRect(origin: CGPoint(x: (self.view.frame.width / 2) - 100, y: 500), size: CGSize(width: 200, height: 200)))
                oS.backgroundColor = UIColor.orange
                return oS
            }()
    
            self.slider = UISlider(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: CGSize(width: self.view.frame.width - 400, height: 50)))
            self.slider.addTarget(self, action: #selector(self.sliderValueDidChange), for: UIControlEvents.allTouchEvents)
            self.slider.minimumValue = -5
            self.slider.maximumValue = 5
            self.slider.value = 0
    
            self.sliderLabel = UILabel(frame: CGRect(origin: CGPoint(x: self.view.frame.width - 100, y: 100), size: CGSize(width : 50, height: 50)))
            self.sliderLabel.backgroundColor = UIColor.red
            self.sliderLabel.textAlignment = NSTextAlignment.center
            self.sliderLabel.textColor = UIColor.white
            self.sliderLabel.text = String(self.slider.value)
    
            // Assemble
            self.view.addSubview(self.orangeSquare)
            self.view.addSubview(self.slider)
            self.view.addSubview(self.sliderLabel)
    
            // Configure dynamic behaviours
    
            self.dynamicAnimator = UIDynamicAnimator(referenceView: self.view)
            self.gravityBehaviour = UIGravityBehavior(items: [self.orangeSquare])
            self.gravityBehaviour.gravityDirection = CGVector(dx: 0, dy: 0)
    
            // Configure boundaries
            let boundaries : UICollisionBehavior = UICollisionBehavior(items: [self.orangeSquare])
            boundaries.translatesReferenceBoundsIntoBoundary = true
    
            self.dynamicAnimator.addBehavior(self.gravityBehaviour)
            self.dynamicAnimator.addBehavior(boundaries)
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func sliderValueDidChange() {
            // When the slider value changes, update the label text and the gravity vector
            self.sliderLabel.text = String((round(self.slider.value) * 10) / 10)
            self.gravityBehaviour.gravityDirection = CGVector(dx: 0, dy: CGFloat(-1 * self.slider.value))
        }
    
    }
    

    Hope that helps. All best!