Swift:下拉以解除`UITableViewController`

时间:2015-11-19 23:22:01

标签: ios xcode swift uitableview uiscrollview

我想撤下来解雇UITableViewController所以我使用了scrollViewDidScroll方法,但它没有用!

    class CommentViewController: PFQueryTableViewController {

        private let tableHeaderHeight: CGFloat = 350.0



extension CommentViewController
{
    override func scrollViewDidScroll(scrollView: UIScrollView)
    {



            // Pull down to dismiss TVC 
            let offsetY = scrollView.contentOffset.y
            let adjustment: CGFloat = 130.0

            // for later use
            if (-offsetY) > (tableHeaderHeight+adjustment) {
                self.dismissViewControllerAnimated(true, completion: nil)
                }
 }
    }

4 个答案:

答案 0 :(得分:8)

您必须实现额外的平移手势识别器,它将同时识别scrollView的平移手势识别器。然后,当表格视图已滚动到顶部时,您可以确定用户是否正在用手指平移。 e.g。

var isTrackingPanLocation = false
var panGestureRecognizer : UIPanGestureRecognizer!

public override func viewDidLoad()
{
    super.viewDidLoad()
    tableView.bounces = false
    panGestureRecognizer = UIPanGestureRecognizer(target: self, action: "panRecognized:")
    panGestureRecognizer.delegate = self
    tableView.addGestureRecognizer(panGestureRecognizer)
}

public func panRecognized(recognizer:UIPanGestureRecognizer)
{
    if recognizer.state == .Began && tableView.contentOffset.y == 0
    {
        recognizer.setTranslation(CGPointZero, inView : tableView)

        isTrackingPanLocation = true
    }
    else if recognizer.state != .Ended && recognizer.state != .Cancelled && 
                    recognizer.state != .Failed && isTrackingPanLocation
    {
        let panOffset = recognizer.translationInView(tableView)

        // determine offset of the pan from the start here. 
        // When offset is far enough from table view top edge - 
        // dismiss your view controller. Additionally you can 
        // determine if pan goes in the wrong direction and 
        // then reset flag isTrackingPanLocation to false

        let eligiblePanOffset = panOffset.y > 200
        if eligiblePanOffset
        {
            recognizer.enabled = false
            recognizer.enabled = true
            self.dismissViewControllerAnimated(true, completion: nil)
        }

        if panOffset.y < 0
        {
            isTrackingPanLocation = false
        }
    }
    else
    {
        isTrackingPanLocation = false
    }
}

public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, 
    shouldRecognizeSimultaneouslyWithGestureRecognizer 
                    otherGestureRecognizer : UIGestureRecognizer)->Bool
{
    return true
}

答案 1 :(得分:7)

Swift 4

var panGestureRecognizer : UIPanGestureRecognizer!

override func viewDidLoad() {
    mainTableView.bounces = true
    panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.panRecognized))
    panGestureRecognizer.delegate = self
    mainTableView.addGestureRecognizer(panGestureRecognizer)
}


@objc func panRecognized(recognizer: UIPanGestureRecognizer) {
    if recognizer.state == .began && mainTableView.contentOffset.y == 0 {

    } else if recognizer.state != .ended && recognizer.state != .cancelled && recognizer.state != .failed {
        let panOffset = recognizer.translation(in: mainTableView)
        let eligiblePanOffset = panOffset.y > 300
        if eligiblePanOffset {
            recognizer.isEnabled = false
            recognizer.isEnabled = true
            self.dismiss(animated: true, completion: nil)
        }
    }
}


func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

答案 2 :(得分:2)

为什么不在scrollViewDidScroll中放置print(offsetY)。我怀疑npm -v永远不会满足,因为橡皮筋会导致tableview在它解除视图控制器之前反弹

答案 3 :(得分:0)

对于在2019年看到此内容的人们来说,更现代的方法将使用UIGestureRecognizerDelegate方法,而不是在视图控制器中保留额外的状态。例如:

private weak var panFromTop: UIPanGestureRecognizer?

override func viewDidLoad() {
    super.viewDidLoad()

    // Add pan gesture recognizer
    let panFromTop = UIPanGestureRecognizer(target: self, action: #selector(handlePanFromTop(_:)))
    panFromTop.delegate = self
    tableView.addGestureRecognizer(panFromTop)
    self.panFromTop = panFromTop
}

@objc func handlePanFromTop(_ recognizer: UIPanGestureRecognizer) {
    switch recognizer.state {
    case .began:
        // TODO: BEGIN YOUR ANIMATION HERE
    case .changed:
        // TODO: UPDATE YOUR ANIMATION HERE
    default:
        let translation = recognizer.translation(in: view)
        let velocity = recognizer.velocity(in: view)
        if ((translation.y + velocity.y) / view.bounds.height) > 0.5 {
            // TODO: FINISH YOUR ANIMATION HERE
        } else {
            // TODO: CANCEL YOUR ANIMATION HERE
        }
    }
}

仅在表格视图顶部禁用跳动:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if scrollView.contentOffset.y < 0 {
        scrollView.setContentOffset(.zero, animated: false)
    }
}

然后实现手势识别器委托方法:

func gestureRecognizer(
    _ gestureRecognizer: UIGestureRecognizer,
    shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
) -> Bool {
    return true
}

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    guard let recognizer = gestureRecognizer as? UIPanGestureRecognizer,
        recognizer === panFromTop else {
        // Only require special conditions for the panFromTop gesture recognizer
        return true
    }

    // Require the scroll view to be at the top,
    // and require the pan to start by dragging downward
    return (
        tableView.contentOffset.y <= 0 &&
        recognizer.velocity(in: view).y > 0
    )
}