Permalink
Browse files

Initial Commit

  • Loading branch information...
lkzhao committed Dec 16, 2015
0 parents commit fe3364d0cb9db838b44fb4bd154e6dda0337c616
@@ -0,0 +1,30 @@
#
# Be sure to run `pod lib lint ElasticTransition.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = "ElasticTransition"
s.version = "1.0.0"
s.summary = "A UIKit custom modal transition that simulates an elastic drag. Written in Swift."
s.description = <<-DESC
Best for side menu and navigation transition.
DESC
s.homepage = "https://github.com/lkzhao/ElasticTransition"
# s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
s.license = 'MIT'
s.author = { "Luke" => "lzhaoyilun@gmail.com" }
s.source = { :git => "https://github.com/lkzhao/ElasticTransition.git", :tag => s.version.to_s }
s.platform = :ios, '9.0'
s.requires_arc = true
s.source_files = 'ElasticTransition/*.swift'
s.frameworks = ['UIKit', 'Foundation']
# s.dependency 'AFNetworking', '~> 2.3'
end
@@ -0,0 +1,96 @@
//
// ElasticMenuViewController.swift
// ElasticDropdownMenu
//
// Created by Luke Zhao on 2015-11-30.
// Copyright © 2015 lukezhao. All rights reserved.
//
import UIKit
class ElasticMenuViewController: UIViewController, ElasticMenuTransitionDelegate {
var menuView: UIView!{
return tableView
}
var tableView: UITableView!
var edge:UIRectEdge{
return .Left
}
var menuWidthConstraint: NSLayoutConstraint!
var menuWidth:CGFloat{
get{
return menuWidthConstraint.constant
}
set{
menuWidthConstraint.constant = newValue
view.layoutIfNeeded()
}
}
var backgroundColor:UIColor?{
didSet{
view.backgroundColor = backgroundColor
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: CGRectZero)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.opaque = false
tableView.backgroundColor = UIColor.clearColor()
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
view.addSubview(tableView)
tableView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
tableView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true
if edge == .Left{
tableView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
}else{
tableView.rightAnchor.constraintEqualToAnchor(view.rightAnchor).active = true
}
menuWidthConstraint = tableView.widthAnchor.constraintEqualToConstant(300)
menuWidthConstraint.active = true
view.layoutIfNeeded()
backgroundColor = UIColor(red: 83/255, green: 91/255, blue: 97/255, alpha: 1.0)
tableView.contentInset = UIEdgeInsetsMake(60, 0, 0, 0)
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
private let menu = [
"Please subclass",
"ElasticMenuViewController",
"and override",
"UITableViewDelegate &",
"UITableViewDataSource methods",
"to show your own content"
]
}
extension ElasticMenuViewController:UITableViewDelegate, UITableViewDataSource{
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: nil)
cell.textLabel?.text = menu[indexPath.row]
cell.backgroundColor = UIColor.clearColor()
cell.textLabel?.textColor = UIColor.whiteColor()
cell.selectionStyle = .None
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menu.count
}
}
@@ -0,0 +1,174 @@
//
// ElasticShapeLayer.swift
// ElasticDropdownMenu
//
// Created by Luke Zhao on 2015-11-26.
// Copyright © 2015 lukezhao. All rights reserved.
//
import UIKit
let π:CGFloat = CGFloat(M_PI)
enum Edge{
case Top, Bottom, Left, Right
func opposite() -> Edge{
switch self {
case .Left:
return .Right
case .Right:
return .Left
case .Bottom:
return .Top
case .Top:
return .Bottom
}
}
func toUIRectEdge() -> UIRectEdge{
switch self {
case .Left:
return .Left
case .Right:
return .Right
case .Bottom:
return .Bottom
case .Top:
return .Top
}
}
}
extension CGPoint{
func transform(t:CGAffineTransform) -> CGPoint{
return CGPointApplyAffineTransform(self, t)
}
}
class ElasticShapeLayer: CAShapeLayer {
var edge:Edge = .Bottom{
didSet{
path = currentPath()
}
}
var dragPoint:CGPoint = CGPointZero{
didSet{
path = currentPath()
}
}
var radiusFactor:CGFloat = 0.25{
didSet{
if radiusFactor < 0{
radiusFactor = 0
}
}
}
var clip:Bool = false
override init() {
super.init()
backgroundColor = UIColor.clearColor().CGColor
fillColor = UIColor.blackColor().CGColor
actions = ["path" : NSNull(), "position" : NSNull(), "bounds" : NSNull()]
}
override init(layer: AnyObject) {
super.init(layer: layer)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func currentPath() -> CGPath {
let centerPoint = dragPoint
let leftPoint:CGPoint,rightPoint:CGPoint,bottomRightPoint:CGPoint,bottomLeftPoint:CGPoint
switch edge{
case .Top:
leftPoint = CGPointMake(0 - max(0,bounds.width/2 - dragPoint.x), bounds.minY)
rightPoint = CGPointMake(bounds.width + max(0,dragPoint.x-bounds.width/2), bounds.minY)
bottomRightPoint = CGPointMake(bounds.maxX, bounds.maxY)
bottomLeftPoint = CGPointMake(bounds.minX, bounds.maxY)
case .Bottom:
leftPoint = CGPointMake(bounds.width + max(0,dragPoint.x-bounds.width/2), bounds.maxY)
rightPoint = CGPointMake(0 - max(0,bounds.width/2 - dragPoint.x), bounds.maxY)
bottomRightPoint = CGPointMake(bounds.minX, bounds.minY)
bottomLeftPoint = CGPointMake(bounds.maxX, bounds.minY)
case .Left:
leftPoint = CGPointMake(bounds.minX, bounds.height + max(0,dragPoint.y-bounds.height/2))
rightPoint = CGPointMake(bounds.minX, 0 - max(0,bounds.height/2 - dragPoint.y))
bottomRightPoint = CGPointMake(bounds.maxX, bounds.minY)
bottomLeftPoint = CGPointMake(bounds.maxX, bounds.maxY)
case .Right:
leftPoint = CGPointMake(bounds.maxX, 0 - max(0,bounds.height/2 - dragPoint.y))
rightPoint = CGPointMake(bounds.maxX, bounds.height + max(0,dragPoint.y-bounds.height/2))
bottomRightPoint = CGPointMake(bounds.minX, bounds.maxY)
bottomLeftPoint = CGPointMake(bounds.minX, bounds.minY)
}
let shapePath = UIBezierPath()
shapePath.moveToPoint(leftPoint)
if radiusFactor>=0.5{
let rightControl:CGPoint,leftControl:CGPoint;
switch edge{
case .Top,.Bottom:
rightControl = CGPointMake((rightPoint.x - centerPoint.x)*0.8+centerPoint.x, centerPoint.y)
leftControl = CGPointMake((centerPoint.x - leftPoint.x)*0.2+leftPoint.x, centerPoint.y)
case .Left,.Right:
rightControl = CGPointMake(centerPoint.x, (rightPoint.y - centerPoint.y)*0.8+centerPoint.y)
leftControl = CGPointMake(centerPoint.x, (centerPoint.y - leftPoint.y)*0.2+leftPoint.y)
}
shapePath.addCurveToPoint(
centerPoint,
controlPoint1: leftPoint,
controlPoint2: leftControl)
shapePath.addCurveToPoint(
rightPoint,
controlPoint1: centerPoint,
controlPoint2: rightControl)
}else{
let rightControl:CGPoint,leftControl:CGPoint,rightRightControl:CGPoint,leftLeftControl:CGPoint;
switch edge{
case .Top,.Bottom:
rightControl = CGPointMake((rightPoint.x - centerPoint.x)*radiusFactor+centerPoint.x, (centerPoint.y + rightPoint.y)/2)
leftControl = CGPointMake((centerPoint.x - leftPoint.x)*(1-radiusFactor)+leftPoint.x, (centerPoint.y + leftPoint.y)/2)
// | --- (1 - 2*radiusFactor) --- leftLeftControl --- radiusFactor --- leftControl --- radiusFactor --- center --- ...
rightRightControl = CGPointMake((rightPoint.x - centerPoint.x)*(2*radiusFactor)+centerPoint.x, (centerPoint.y > rightPoint.y ? min : max)(centerPoint.y,rightPoint.y))
leftLeftControl = CGPointMake((centerPoint.x - leftPoint.x)*(1-2*radiusFactor)+leftPoint.x, (centerPoint.y > rightPoint.y ? min : max)(centerPoint.y,leftPoint.y))
case .Left,.Right:
rightControl = CGPointMake((centerPoint.x + rightPoint.x)/2, (rightPoint.y - centerPoint.y)*radiusFactor+centerPoint.y)
leftControl = CGPointMake((centerPoint.x + leftPoint.x)/2, (centerPoint.y - leftPoint.y)*(1-radiusFactor)+leftPoint.y)
rightRightControl = CGPointMake((centerPoint.x > rightPoint.x ? min : max)(centerPoint.x,rightPoint.x),(rightPoint.y - centerPoint.y)*(2*radiusFactor)+centerPoint.y)
leftLeftControl = CGPointMake((centerPoint.x > rightPoint.x ? min : max)(centerPoint.x,leftPoint.x), (centerPoint.y - leftPoint.y)*(1-2*radiusFactor)+leftPoint.y)
}
shapePath.addCurveToPoint(
leftControl,
controlPoint1: leftPoint,
controlPoint2: leftLeftControl)
shapePath.addCurveToPoint(
rightControl,
controlPoint1: leftControl,
controlPoint2: centerPoint)
shapePath.addCurveToPoint(
rightPoint,
controlPoint1: rightControl,
controlPoint2: rightRightControl)
}
shapePath.addLineToPoint(bottomRightPoint)
shapePath.addLineToPoint(bottomLeftPoint)
shapePath.addLineToPoint(leftPoint)
shapePath.closePath()
return shapePath.CGPath
}
}
Oops, something went wrong.

0 comments on commit fe3364d

Please sign in to comment.