             return .None
         }
     }
+    
+    public var description: String {
+        switch self {
+        case ZLSwipeableViewDirection.None:
+            return "None"
+        case ZLSwipeableViewDirection.Left:
+            return "Left"
+        case ZLSwipeableViewDirection.Right:
+            return "Right"
+        case ZLSwipeableViewDirection.Up:
+            return "Up"
+        case ZLSwipeableViewDirection.Down:
+            return "Down"
+        case ZLSwipeableViewDirection.Horizontal:
+            return "Horizontal"
+        case ZLSwipeableViewDirection.Vertical:
+            return "Vertical"
+        case ZLSwipeableViewDirection.All:
+            return "All"
+        default:
+            return "Unknown"
+        }
+    }
 }
 
 public class ZLSwipeableView: UIView {
     // MARK: - Public
-    // Data Source
+    // MARK: Data Source
     public var numPrefetchedViews = 3
-    public var nextView: (() -> UIView)? {
-        didSet {
-            loadViews()
-        }
-    }
-    // Animation
+    public var nextView: (() -> UIView?)?
+    // MARK: Animation
     public var animateView: (view: UIView, index: Int, views: [UIView], swipeableView: ZLSwipeableView) -> () = {
         func toRadian(degree: CGFloat) -> CGFloat {
             return degree * CGFloat(M_PI/100)

    
    override public func layoutSubviews() {
        super.layoutSubviews()
        
        containerView.frame = bounds
    }
    
    // MARK: Animator
    private var animator: UIDynamicAnimator!
    // anchorView
    static private let anchorViewWidth = CGFloat(1000)
    private var anchorView = UIView(frame: CGRect(x: 0, y: 0, width: anchorViewWidth, height: anchorViewWidth))
    private var anchorContainerView = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))

            
            let directionChecked = ZLSwipeableViewDirection.fromPoint(translation) & direction != .None
            let signChecked = CGPoint.areInSameTheDirection(translation, p2: velocity)
            let translationChecked = abs(translation.x) > translationThreshold * bounds.width ||
                                     abs(translation.y) > translationThreshold * bounds.height
            let velocityChecked = velocityMag > velocityThreshold
            if directionChecked && signChecked && (translationChecked || velocityChecked){
                let normalizedTrans = translation.normalized
                let throwVelocity = max(velocityMag, velocityThreshold)
                let directionVector = CGVector(dx: normalizedTrans.x*throwVelocity, dy: normalizedTrans.y*throwVelocity)

                pushView(aView, fromPoint: location, inDirection: directionVector)
                removeTopView()
                didSwipe?(view: aView, inDirection: ZLSwipeableViewDirection.fromPoint(translation))
                loadViews()
            } else {
                snapView(aView, toPoint: convertPoint(center, fromView: superview))
                didCancel?(view: aView)
            }
            didEnd?(view: aView, atLocation: location)
        default:
            break
        }
