How to make sure that completion will be called in animateWithDuration()

I have a function which switches between 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





It’s triggered by several button on the screen like this:

@IBAction func showFontsTool(sender: UIBarButtonItem) {
   toggleCollectionView(fontsCV, targetName:"fontsCV")

If user tap on buttons very fast, completion block won’t be called sometimes and self.view.userInteractionEnabled won’t be enabled. How can I make sure completion block will be called always after starting animation?

Source: ios

Leave a Reply