当另一个 UIScrollView 滚动时停止动画 UIScrollView
Posted
技术标签:
【中文标题】当另一个 UIScrollView 滚动时停止动画 UIScrollView【英文标题】:Stop an animating UIScrollView when another UIScrollView is scrolled 【发布时间】:2015-07-04 08:47:36 【问题描述】:假设我有多个滚动视图,并且我希望在任何给定时间只打开其中一个 (scrollView.contentOffset != 0
)。因此,当scroll view 1
打开并且scroll view 2
滚动时,scroll view 1
应该以动画方式关闭。当我快速打开scroll view 1
和scroll 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
。
确定
scroll view
是打开还是关闭。
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
当
scroll view
被拉近所有其他scroll view
时。
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
)
将
scroll view
捕捉到offset
0 或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
)
【问题讨论】:
【参考方案1】:嗯...我找到了解决办法。我使用变量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
)
)
【讨论】:
以上是关于当另一个 UIScrollView 滚动时停止动画 UIScrollView的主要内容,如果未能解决你的问题,请参考以下文章
如何将滚动动画从一个uiscrollview“传输”到另一个