ios - 如何确保在 animateWithDuration() 中调用完成

标签 ios swift

我有一个在 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 block 有时不会被调用,self.view.userInteractionEnabled 也不会被启用。如何确保 completion block 总是在开始动画后被调用?

更新

固定功能正常工作:

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                            }
                })
            }

        }

    }

}

最佳答案

这是解决方法:

创建一个 bool 变量 animationTriggering,当您按下按钮时将其自身设置为 true。这个变量可以作为一个标志供你检查;如果为真,则不要再次执行 UIView 动画。您只会在 UIView 动画处于 false 状态时执行它。

UIView 动画完成后,将其设置回 false,以便下次再次触发。

我猜这个问题是由于多线程问题引起的。我以前遇到过这种情况,并且绕过了它,但我真的没有信心声称我知道问题出在哪里。

如果我可以大胆猜测的话,那就是 UIView 动画有一个内部异步线程,如果您发送请求太快,它会相互干扰。

关于ios - 如何确保在 animateWithDuration() 中调用完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30501060/

相关文章:

ios - 解锁iPhone屏幕后如何重新连接到Openfire服务器?

ios - 场景套件 : projectPoint calculated is displaced

swift - 传给#keyPath()的非字符串 "property name"能否独立保存?

html - Mathjax 的 iOS Swift 语法

ios - 在 iPhone 上以两种不同的分辨率同时处理实时视频和静止图像?

ios - 设备旋转时宽度未更新

swift - 接受参数但不返回值的自动关闭

ios - 表达式类型 '(_) -> _ ' 在没有更多上下文的情况下不明确

ios - SocketIOClient-Swift : Unable to authenticate socket server

android - 实体手机上的jquery点击事件问题