Skip to content

Instantly share code, notes, and snippets.

@dobaduc
Last active June 6, 2018 12:33
Show Gist options
  • Save dobaduc/79374c42d3af3756e345 to your computer and use it in GitHub Desktop.
Save dobaduc/79374c42d3af3756e345 to your computer and use it in GitHub Desktop.
Animate an UIView overlapping UINavigationBar ( Solution 1 - Using cloned view)
//
// 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
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment