|
// |
|
// NavigationBarOverlappingDemo.swift |
|
// |
|
// Created by Duc DoBa on 9/8/15. |
|
// Copyright (c) 2015 Duc Doba. All rights reserved. |
|
// |
|
// This example is created to answer to the following StackOverflow question: |
|
// http://stackoverflow.com/questions/32446076/how-to-overlap-uinavigationbar-with-animation |
|
|
|
import UIKit |
|
|
|
class ViewController: UIViewController { |
|
// Simply put an UIImageView right under UINavigationBar to see the result |
|
@IBOutlet weak var imageView: UIImageView! |
|
|
|
// We will animate this object instead of the imageView |
|
// because moving the imageView back and forth between it's super view and window is quite troublesome |
|
lazy var clonedImageView: UIImageView = { |
|
var view = self.imageView.deepCopy() as! UIImageView |
|
let window = UIApplication.sharedApplication().keyWindow |
|
view.hidden = true |
|
window?.addSubview(view) |
|
|
|
return view |
|
}() |
|
|
|
override func viewDidAppear(animated: Bool) { |
|
var longPress = UILongPressGestureRecognizer(target: self, action: Selector("longPress:")) |
|
imageView.addGestureRecognizer(longPress) |
|
imageView.userInteractionEnabled = true |
|
} |
|
|
|
func longPress(gesture:UILongPressGestureRecognizer) { |
|
if gesture.state == UIGestureRecognizerState.Began { |
|
println("user pressed on image") |
|
|
|
self.showImageViewClone() |
|
let bounds = clonedImageView.bounds |
|
UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 0.4, initialSpringVelocity: 10, options: UIViewAnimationOptions.CurveEaseInOut, animations: { |
|
self.clonedImageView.bounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.size.width + 50, height: bounds.size.height + 50) |
|
}, completion: nil) |
|
} |
|
else if gesture.state == UIGestureRecognizerState.Changed { |
|
gesture.state == UIGestureRecognizerState.Began |
|
} |
|
else { |
|
println("user release on image") |
|
|
|
let bounds = clonedImageView.bounds |
|
UIView.animateWithDuration(0.2, animations: { |
|
self.clonedImageView.bounds = self.imageView.bounds |
|
}, completion: { _ in |
|
self.hideImageViewClone() |
|
}) |
|
} |
|
} |
|
|
|
// This method is to ensure that the cloned imageView will appear exactly at the point you want |
|
func showImageViewClone() { |
|
let window = UIApplication.sharedApplication().keyWindow |
|
let origin = imageView.superview!.convertPoint(imageView.frame.origin, toView: window) |
|
|
|
var frame = clonedImageView.frame |
|
frame.origin = origin |
|
clonedImageView.frame = frame |
|
|
|
clonedImageView.hidden = false |
|
imageView.hidden = true |
|
} |
|
|
|
func hideImageViewClone() { |
|
self.imageView.hidden = false |
|
self.clonedImageView.hidden = true |
|
} |
|
} |
|
|
|
extension UIView { |
|
func deepCopy() -> UIView { |
|
|
|
let data = NSKeyedArchiver.archivedDataWithRootObject(self) |
|
let copy = NSKeyedUnarchiver.unarchiveObjectWithData(data)! as! UIView |
|
|
|
return copy |
|
} |
|
} |