Tôi vừa tạo một hướng dẫn về cách tương tác kéo xuống một phương thức để loại bỏ nó. 
http://www.thorntech.com/2016/02/ios-tutorial-close-modal-dragging/
Tôi thấy chủ đề này lúc đầu khá khó hiểu, vì vậy hướng dẫn xây dựng chủ đề này từng bước một.

Nếu bạn chỉ muốn tự chạy mã, đây là repo:
https://github.com/ThornTechPublic/InteractiveModal
Đây là cách tiếp cận tôi đã sử dụng:
Xem bộ điều khiển
Bạn ghi đè hoạt ảnh loại bỏ bằng hoạt ảnh tùy chỉnh. Nếu người dùng đang kéo phương thức, thì interactorsẽ có hiệu lực.
import UIKit
class ViewController: UIViewController {
    let interactor = Interactor()
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let destinationViewController = segue.destinationViewController as? ModalViewController {
            destinationViewController.transitioningDelegate = self
            destinationViewController.interactor = interactor
        }
    }
}
extension ViewController: UIViewControllerTransitioningDelegate {
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return DismissAnimator()
    }
    func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
        return interactor.hasStarted ? interactor : nil
    }
}
Loại bỏ Animator
Bạn tạo một trình hoạt họa tùy chỉnh. Đây là một hoạt ảnh tùy chỉnh mà bạn đóng gói bên trong một UIViewControllerAnimatedTransitioninggiao thức.
import UIKit
class DismissAnimator : NSObject {
}
extension DismissAnimator : UIViewControllerAnimatedTransitioning {
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
        return 0.6
    }
    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        guard
            let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey),
            let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey),
            let containerView = transitionContext.containerView()
            else {
                return
        }
        containerView.insertSubview(toVC.view, belowSubview: fromVC.view)
        let screenBounds = UIScreen.mainScreen().bounds
        let bottomLeftCorner = CGPoint(x: 0, y: screenBounds.height)
        let finalFrame = CGRect(origin: bottomLeftCorner, size: screenBounds.size)
        UIView.animateWithDuration(
            transitionDuration(transitionContext),
            animations: {
                fromVC.view.frame = finalFrame
            },
            completion: { _ in
                transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
            }
        )
    }
}
Tương tác
Bạn phân lớp UIPercentDrivenInteractiveTransitionđể nó có thể hoạt động như một máy trạng thái của bạn. Vì đối tượng tương tác được truy cập bởi cả hai VC, hãy sử dụng nó để theo dõi tiến trình quay.
import UIKit
class Interactor: UIPercentDrivenInteractiveTransition {
    var hasStarted = false
    var shouldFinish = false
}
Bộ điều khiển chế độ xem phương thức
Điều này ánh xạ trạng thái cử chỉ xoay để gọi phương thức tương tác. Các translationInView() ygiá trị xác định xem người dùng vượt qua một ngưỡng. Khi cử chỉ xoay .Ended, bộ tương tác kết thúc hoặc hủy.
import UIKit
class ModalViewController: UIViewController {
    var interactor:Interactor? = nil
    @IBAction func close(sender: UIButton) {
        dismissViewControllerAnimated(true, completion: nil)
    }
    @IBAction func handleGesture(sender: UIPanGestureRecognizer) {
        let percentThreshold:CGFloat = 0.3
        
        let translation = sender.translationInView(view)
        let verticalMovement = translation.y / view.bounds.height
        let downwardMovement = fmaxf(Float(verticalMovement), 0.0)
        let downwardMovementPercent = fminf(downwardMovement, 1.0)
        let progress = CGFloat(downwardMovementPercent)
        guard let interactor = interactor else { return }
        switch sender.state {
        case .Began:
            interactor.hasStarted = true
            dismissViewControllerAnimated(true, completion: nil)
        case .Changed:
            interactor.shouldFinish = progress > percentThreshold
            interactor.updateInteractiveTransition(progress)
        case .Cancelled:
            interactor.hasStarted = false
            interactor.cancelInteractiveTransition()
        case .Ended:
            interactor.hasStarted = false
            interactor.shouldFinish
                ? interactor.finishInteractiveTransition()
                : interactor.cancelInteractiveTransition()
        default:
            break
        }
    }
}