底页ScrollView平移和滚动

时间:2018-07-29 02:44:01

标签: ios scrollview uipangesturerecognizer bottom-sheet

我对Apple的Maps应用如何从工作表上的平移手势转换为scrollView或tableView中的滚动内容手势感兴趣。我将其作为重新创建它的第一步。当工作表停靠时,我一直无法从平移整个工作表转到滚动内容。

有这样的问题和一些库,但是我还没有看到过渡部分的解决方案。

@objc func panGesture(recognizer: UIPanGestureRecognizer) {
    let translation = recognizer.translation(in: view)

    switch recognizer.state {

    // ** Tracking starting offset
    case .began: startingOffset = heightConstraint?.constant ?? 0

    // ** Toggle panGesture and tableView to properly switch between gestures
    case .changed:
        let offset = startingOffset - translation.y
        var minOffset: CGFloat = 0

        mapView.alpha = 1 - (0.5 * (offset / maxOffset))

        // This adds elasticity
        if offset < 0 {
            minOffset = -(0 - offset)/3
        }

        // ** Track bottom sheet with pan gesture by finding the diff
        // be tween translation and starting offset, then constraint
        // this value to be between our top margin and min height
        let currentOffset = min(maxOffset, max(minOffset, offset))
        heightConstraint?.constant = currentOffset

        // ** `offset` == 0 means the sheet is minimized
        // `offset` == `maxOffset` means the sheet is open
        if currentOffset == 0 {
            tableView.contentOffset = .zero
            tableView.isScrollEnabled = false
        } else if currentOffset == maxOffset {
            panGesture.isEnabled = false
            panGesture.isEnabled = true
            tableView.isScrollEnabled = true
        }

    case .ended, .cancelled:
        guard let offset = heightConstraint?.constant else { return }

        // ** Handle last position - if nearer to the top finish out the
        // animation to the top, and vice versa
        var finalOffset: CGFloat = offset > maxOffset/2 ? maxOffset : 0
        let velocity = recognizer.velocity(in: view).y

        // ** Toggle tableView scrollability
        // Handle "flick" action using `velocity`
        if velocity < -100 {
            finalOffset = maxOffset
            tableView.isScrollEnabled = true
        } else if offset > maxOffset/2 && velocity > 200 {
            finalOffset = 0
            tableView.isScrollEnabled = false
        } else {
            tableView.isScrollEnabled = offset > maxOffset/2
        }

        // Dismiss keyboard if dismissing sheet
        if finalOffset == 0 {
            _ = searchField.resignFirstResponder()
        }

        // ** Animate to top or bottom docking position when gesture ends
        // or is cancelled
        heightConstraint?.constant = finalOffset
        UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.2, options: [.curveEaseOut, .allowUserInteraction], animations: { [weak self] in
            guard let strongSelf = self else { return }
            strongSelf.view.layoutIfNeeded()
            strongSelf.mapView.alpha = 1 - (0.5 * (finalOffset / strongSelf.maxOffset))

        }, completion: nil)

    default: ()
    }
}

//UIScrollViewDelegate
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    guard let offset = heightConstraint?.constant else { return }

    // ** Disable panning if scrollView isn't at the top
    panGesture.isEnabled = tableView.contentOffset.y <= 0 || offset == 0

    // ** Don't scroll if bottom sheet is panning down
    if scrollView.contentOffset.y < 0 {
        scrollView.isScrollEnabled = false
        panGesture.isEnabled = true
    }
}

帮助?

0 个答案:

没有答案