滚动另一个 UIScrollView 时停止动画 UIScrollView

Stop an animating UIScrollView when another UIScrollView is scrolled

假设我有多个滚动视图,并且我希望在任何给定时间只打开其中一个 (scrollView.contentOffset != 0)。因此,当 scroll view 1 打开并且 scroll view 2 滚动时,scroll view 1 应该动画关闭。当我快速打开scroll view 1scroll view 2时出现问题;发生这种情况时,scroll view 1 仍在减速,scroll view 2 的打开试图强制 scroll view 1 关闭并中断动画,有时甚至无法关闭。 解决这个问题的一种方法是禁用滚动,直到滚动视图完成减速。但是,我正在寻找可以更无缝地处理此问题的其他解决方案。 我试过了 scrollView.layer.removeAllAnimations()。这不会停止减速动画。我希望 scroll view 1 的动画在滚动 scroll view 2 时立即停止,然后 scroll view 1 可以动画到 contentOffset = 0

Identify if scroll view is opening or closing.

func scrollViewDidScroll(scrollView: UIScrollView) {
    scrollView.bounces = scrollView.contentOffset.x > 20
    if scrollView.contentOffset.x < self.lastContentOffset && scrollView.contentOffset.x < 70 {
        ifOpening = false
    }
    else if scrollView.contentOffset.x > 5 {
        ifOpening = true
    }
    self.lastContentOffset = scrollView.contentOffset.x

}

When a scroll view is dragged close all other scroll view's.

func scrollViewWillBeginDragging(scrollView: UIScrollView) {

    for eachScrollView in taskArrayScrollView{
        if  eachScrollView != scrollView {
            eachScrollView.layer.removeAllAnimations()
            UIView.animateWithDuration(0.2,
                delay: 0.5,
                options: .CurveEaseIn ,
                animations: { eachScrollView.contentOffset.x = 0 },
                completion: nil
            )
        }
    }
}

To snap the scroll view to either offset 0 or 70

func scrollViewDidEndDragging(scrollViewa: UIScrollView, willDecelerate decelerate: Bool) {
    let intialContentOffset = scrollViewa.contentOffset.x
    var originalContentOffset: CGFloat
    var finalContentOffset: CGFloat
    var minOffset: CGFloat

    if intialContentOffset == boundOfScreen.width{
        return
    }

    if ifOpening{
        minOffset = 20.0
        originalContentOffset = 0
        finalContentOffset = 70
    }

    else {
        minOffset = 50.0
        originalContentOffset = 0
        finalContentOffset = 70
    }

    if (!decelerate){
        if intialContentOffset < minOffset {
            UIView.animateWithDuration(0.2,
                delay: 0.1,
                options: .CurveEaseIn ,
                animations: { scrollViewa.contentOffset.x = originalContentOffset },
                completion: {
                    finished in scrollViewa.userInteractionEnabled = true
                }
            )
        }
        else {
            UIView.animateWithDuration(0.2,
                delay: 0.1,
                options: .CurveEaseIn ,
                animations: { scrollViewa.contentOffset.x = finalContentOffset },
                completion: {
                    finished in scrollViewa.userInteractionEnabled = true
                }
            )
        }
    }
}


func scrollViewDidEndDecelerating(scrollViewb: UIScrollView) {
    let intialContentOffset = scrollViewb.contentOffset.x
    var originalContentOffset: CGFloat
    var finalContentOffset: CGFloat
    var minOffset: CGFloat
    //println("intialContentOffset: \(intialContentOffset)")

    if ifOpening{
        minOffset = 20.0
        originalContentOffset = 0
        finalContentOffset = 70
        //println("dec: opening")
    }

    else {
        minOffset = 50.0
        originalContentOffset = 0
        finalContentOffset = 70
        //println("dec: closing")
    }


    if intialContentOffset < minOffset {
        UIView.animateWithDuration(0.2,
            delay: 0.1,
            options: .CurveEaseIn ,
            animations: {scrollViewb.contentOffset.x = originalContentOffset },
            completion: {
                finished in scrollViewb.userInteractionEnabled = true
            }
        )
    }
    else {
        UIView.animateWithDuration(0.2,
            delay: 0.1,
            options: .CurveEaseIn ,
            animations: {scrollViewb.contentOffset.x = finalContentOffset },
            completion: {
                finished in scrollViewb.userInteractionEnabled = true
            }

        )
    }
}

好吧...我找到了解决方法。我使用变量 viewOpenCounter 来跟踪是否打开了另一个 scroll view,如果是,则在完成动画后关闭当前正在动画的 scroll view。不确定这是否有效。

func scrollViewDidScroll(scrollView: UIScrollView) {

    scrollView.bounces = scrollView.contentOffset.x > 20

    if scrollView.contentOffset.x < self.lastContentOffset && scrollView.contentOffset.x < 70 {
        isOpening = false
    }
    else if scrollView.contentOffset.x > 5 {
        isOpening = true
        viewOpenCounter = true
    }
    self.lastContentOffset = scrollView.contentOffset.x
}

func scrollViewWillBeginDragging(scrollView: UIScrollView) {
    if !viewOpenCounter {
        for eachScrollView in taskArrayScrollView {
            if  eachScrollView != scrollView {
                UIView.animateWithDuration(0.2,
                    delay: 0.5,
                    options: .CurveEaseIn ,
                    animations: { eachScrollView.contentOffset.x = 0 },
                    completion: nil
                )}
        }
    }
}
 func scrollViewDidEndDragging(scrollViewa: UIScrollView, willDecelerate decelerate: Bool) {

    viewOpenCounter = false

    let intialContentOffset = scrollViewa.contentOffset.x
    var originalContentOffset: CGFloat
    var finalContentOffset: CGFloat
    var minOffset: CGFloat

    if intialContentOffset == boundOfScreen.width{
        return
    }

    if isOpening{
        minOffset = 20.0
        originalContentOffset = 0
        finalContentOffset = 70
    }

    else {
        minOffset = 50.0
        originalContentOffset = 0
        finalContentOffset = 70
    }

    if (!decelerate){
        //println("no dec \(intialContentOffset)")

        if intialContentOffset < minOffset {
            UIView.animateWithDuration(0.2,
                delay: 0.1,
                options: .CurveEaseIn ,
                animations: { scrollViewa.contentOffset.x = originalContentOffset },
                completion: {
                    finished in scrollViewa.userInteractionEnabled = true
                    if self.viewOpenCounter {
                        UIView.animateWithDuration(0.2, animations: {
                            scrollViewa.contentOffset.x = 0
                        },
                            completion: {
                                finished in
                                self.viewOpenCounter = false
                            }
                        )
                    }
                }
            )
        }
        else {
            UIView.animateWithDuration(0.2,
                delay: 0.1,
                options: .CurveEaseIn ,
                animations: { scrollViewa.contentOffset.x = finalContentOffset },
                completion: {
                    finished in scrollViewa.userInteractionEnabled = true
                    if self.viewOpenCounter {
                        UIView.animateWithDuration(0.2, animations: {
                            scrollViewa.contentOffset.x = 0

                        },
                            completion: {
                                finished in
                                self.viewOpenCounter = false
                            }
                        )
                    }
                }
            )
        }
    }
}

 func scrollViewDidEndDecelerating(scrollViewb: UIScrollView) {

    viewOpenCounter = false

    let intialContentOffset = scrollViewb.contentOffset.x
    var originalContentOffset: CGFloat
    var finalContentOffset: CGFloat
    var minOffset: CGFloat
    //println("intialContentOffset: \(intialContentOffset)")

    if isOpening{
        minOffset = 20.0
        originalContentOffset = 0
        finalContentOffset = 70
        //println("dec: opening")
    }

    else {
        minOffset = 50.0
        originalContentOffset = 0
        finalContentOffset = 70
        //println("dec: closing")
    }


    if intialContentOffset < minOffset {
        UIView.animateWithDuration(0.2,
            delay: 0.1,
            options: .CurveEaseIn ,
            animations: {scrollViewb.contentOffset.x = originalContentOffset },
            completion: {
                finished in scrollViewb.userInteractionEnabled = true
                if self.viewOpenCounter {
                    UIView.animateWithDuration(0.2, animations: {
                        scrollViewb.contentOffset.x = 0
                    },
                        completion: {
                            finished in
                            self.viewOpenCounter = false
                        }
                    )
                }
            }
        )
    }
    else {
        UIView.animateWithDuration(0.2,
            delay: 0.1,
            options: .CurveEaseIn ,
            animations: {scrollViewb.contentOffset.x = finalContentOffset },
            completion: {
                finished in scrollViewb.userInteractionEnabled = true
                if self.viewOpenCounter {
                    UIView.animateWithDuration(0.2, animations: {
                        scrollViewb.contentOffset.x = 0
                    },
                        completion: {
                            finished in
                            self.viewOpenCounter = false
                        }
                    )
                }
            }

        )
    }
}