Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I animate UIImageView when user drags MKMapView?

I have a UIImageView with an image there, this image is a typical map picker. I put it on the map in storyboard and assigned some constraints.

When user drags around my map, that image stays untouched, I want to find a way of animating it - basically I want to squish it a little so it looks as it's dragged.

I already have two methods:

func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {

} 

and

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {

}

But I don't know how to animate the change to UIImageView.

I tried adding to regionWillChangeAnimated the following code:

myPositionPicker.animate(withDuration: 1.5, delay: 0.05 * Double(index), usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
        yawpPositionPicker.transform = CGAffineTransform(translationX: 0, y: 0)
    }, completion: nil)

(where myPositionPicker is my UIImageView), but I'm getting error

Static member animate cannot be used on instance of type UIImageView

I think the best animation for me would be UIViewAnimationOptions.curveEaseIn but I don't know how to attach it to my UIImageView. Can you give me any hint?

like image 999
user3766930 Avatar asked Dec 08 '16 18:12

user3766930


1 Answers

👋

First of all, you are trying to use static method "animate" on instance myPositionPicker. And it's wrong. Just replace

myPositionPicker.animate(withDuration: 1.5, delay: 0.05 * Double(index), usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
    yawpPositionPicker.transform = CGAffineTransform(translationX: 0, y: 0)
}, completion: nil)

With:

UIView.animate(withDuration: 1.5, delay: 0.05 * Double(index), usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
    // Do whatever animations you want here.
}, completion: nil)

Next, if you want to create some simple animations (Like changing of UIImageView position or changing it's size) - you could just use your already created constraints and don't use affine transforms.

For example, if your image view is centered vertically with your map view. First, create a special @IBOutlet for this constraint in your UIViewController:

@IBOutlet var pickerCenterYConsraint: NSLayoutConstraint!

Second, connect this outlet to constraint in storyboard.

Third, as I understood your view controller is a delegate of your map view. So, let's implement map view delegate protocol like this:

func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
    UIView.animate(withDuration: 1.5, delay: 0.05, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
        self.pickerCenterYConsraint.constant = 25.0
        self.view.layoutIfNeeded()
    }, completion: nil)
}

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    UIView.animate(withDuration: 1.5, delay: 0.05, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
        self.pickerCenterYConsraint.constant = 0.0
        self.view.layoutIfNeeded()
    }, completion: nil)
}

And... that's all!🤗 Now your image view will be animated during map view dragging. If you don't like this solution - you could create your own animations based on constraints. Basically you could do a lot of things with constraints. Except rotations, for example.

like image 138
Simbos Avatar answered Oct 03 '22 06:10

Simbos