我有一个在UICollectionView:
之间切换的函数func toggleCollectionView(target: NSObject, targetName:String){
self.view.userInteractionEnabled = false
if let tempTarget = target as? UICollectionView {
//if selected item is same as active one, won't do anything
if(targetName != activeToolbarName){
tempTarget.hidden = false
tempTarget.frame.origin.y = screenSize.height
UIView.animateWithDuration(0.4, delay: 0.0, options: .CurveEaseOut, animations: {
if let tempActiveToolbar = self.activeToolbar as? UICollectionView {
tempActiveToolbar.frame.origin.y = self.screenSize.height
}
tempTarget.frame.origin.y = self.screenSize.height - tempTarget.frame.height - self.selectorsContainer.frame.height
}, completion: { finished in
if let tempActiveToolbar = self.activeToolbar as? UICollectionView {
tempActiveToolbar.hidden = true
self.activeToolbar = target
self.activeToolbarName = targetName
self.view.userInteractionEnabled = true
}
})
}
}
}
它由屏幕上的几个按钮触发,如下所示:
@IBAction func showFontsTool(sender: UIBarButtonItem) {
toggleCollectionView(fontsCV, targetName:"fontsCV")
}
如果用户非常快速点击按钮,有时不会调用completion
块,并且不会启用self.view.userInteractionEnabled
。如何确保在开始动画后始终调用completion
块?
更新
固定功能正常:
func toggleCollectionView(target: NSObject, targetName:String){
if let tempTarget = target as? UICollectionView {
//if selected item is same as active one, won't do anything
if(targetName != activeToolbarName){
tempTarget.hidden = false
tempTarget.frame.origin.y = screenSize.height
if (runningAnimation == false){
runningAnimation = true
self.activeToolbarName = targetName
UIView.animateWithDuration(0.4, delay: 0.0, options: .CurveEaseOut, animations: {
if let tempActiveToolbar = self.activeToolbar as? UICollectionView {
tempActiveToolbar.frame.origin.y = self.screenSize.height
}
tempTarget.frame.origin.y = self.screenSize.height - tempTarget.frame.height - self.selectorsContainer.frame.height
}, completion: { finished in
if let tempActiveToolbar = self.activeToolbar as? UICollectionView {
tempActiveToolbar.hidden = true
self.activeToolbar = target
self.runningAnimation = false }
})
}
}
}
}
答案 0 :(得分:1)
这是解决方法:
创建一个布尔变量animationTriggering
,在按下按钮时将其自身设置为true。这个变量可以作为你检查的标志;如果是,则不要再次执行UIView动画。只有当它处于false状态时才会执行UIView动画。
UIView动画完成后,将其设置为false,以便下次再次触发。
我猜这个问题是由多线程问题引起的。我之前遇到过这种情况而且我做到了这一点,但我真的没有信心声称我知道问题是什么。
如果我可以冒险猜测,那就是UIView动画有一个内部异步线程,如果你发送请求的速度太快,它会互相干扰。
答案 1 :(得分:1)
首先,您必须声明一个Global Bool变量。
var isAnimating:BOOL = False
现在按钮操作,
@IBAction func showFontsTool(sender: UIBarButtonItem) {
if(!isAnimating) //if animation is not happening then call the method
{
toggleCollectionView(fontsCV, targetName:"fontsCV")
}
else //if animation is happening then return
{
return;
}
}
现在使用动画方法func toggleCollectionView
,设置isAnimating
变量的值,如下所示: -
func toggleCollectionView(target: NSObject, targetName:String){
isAnimating=True //notify animation has started, so that this method don't get fire on button click
self.view.userInteractionEnabled = false
if let tempTarget = target as? UICollectionView {
//if selected item is same as active one, won't do anything
if(targetName != activeToolbarName){
tempTarget.hidden = false
tempTarget.frame.origin.y = screenSize.height
UIView.animateWithDuration(0.4, delay: 0.0, options: .CurveEaseOut, animations: {
if let tempActiveToolbar = self.activeToolbar as? UICollectionView {
tempActiveToolbar.frame.origin.y = self.screenSize.height
}
tempTarget.frame.origin.y = self.screenSize.height - tempTarget.frame.height - self.selectorsContainer.frame.height
}, completion: { finished in
if let tempActiveToolbar = self.activeToolbar as? UICollectionView {
tempActiveToolbar.hidden = true
self.activeToolbar = target
self.activeToolbarName = targetName
self.view.userInteractionEnabled = true
isAnimating=False //now set bool value on this completion handler to false so that this method can get fired again.
}
})
}
}
}