为什么在动画中使用self.view.layoutIfNeeded()导致应用程序冻结?

时间:2017-02-01 08:52:53

标签: ios iphone swift animation layout

在我的应用程序中,一旦用户进入该应用程序,我在仪表板上有太多动画只出现一次-i.e当用户第一次进入应用程序时 -

我在调用另一个动画函数的调用upperViewAnimation()函数中的 viewDidAppear 中以这种方式执行动画,更清楚这是使用过的代码:

 func upperViewAnimation() {

    contianerTop.constant = 0
    UIView.animateWithDuration(0.45, animations: { () -> Void in

        self.view.layoutIfNeeded()

        }, completion:{(finished)  in

            if finished {
                if noInternetConnection && !noInternetConnectionPopup {
                    self.noConnectionViewHeight.constant = 50
                    UIView.animateWithDuration(0.3, animations: {
                    self.view.layoutIfNeeded()
                    })

                    noInternetConnectionPopup = true
                    openNoInternetConnection()
                }
                else if noInternetConnection {
                    self.noConnectionViewHeight.constant = 50
                    UIView.animateWithDuration(0.3, animations: {
                    self.view.layoutIfNeeded()
                    })

                }
                else {
                    self.noConnectionViewHeight.constant = 0
                    UIView.animateWithDuration(0.3, animations: {
                    self.view.layoutIfNeeded()
                        }, completion: { (finished) in
                           self.pullToRefreshAction()
                    })
                }
                self.notificationButtonAnimationAndMenuButton()
                self.moreAppsLabel.hidden = false
            }
    })
}

func pullToRefreshAction() {
    pullToRefreshContainsFailure = false
    addBlurToCellDelegate?.removeBlurFromAllCells()

    if firstAppear || userLoggedIn {
        self.firstAppear = false
        userLoggedIn = false
        loadingView2.removeFromSuperview()
        sucessView.removeFromSuperview()
        var viewHeight:CGFloat = 50
        if isiPadFlag {
            viewHeight = 60
        }
        loadingView2 = NSBundle.mainBundle().loadNibNamed("GettingDataView", owner: self, options: nil)[0] as! GettingDataView
        loadingView2.frame = CGRect(x: 0, y: 0, width: screenWidth, height: viewHeight)
        self.noConnectionView.addSubview(loadingView2)
        loadingView2.initView()
        gettingDataForFirstTime = true

        if showPullToRefreshBool {
                self.noConnectionViewHeight.constant = 50
            }
            UIView.animateWithDuration(0.3, animations: {
                self.view.layoutIfNeeded()
            })
        }
        else {
            self.noConnectionViewHeight.constant = 0
        }
    }  if !gettingData  {
          // I called  requests to get data

        }
}

当我执行上一个代码时,我的应用程序有时会冻结,似乎布局永远不会改变(即应用程序似乎永远不会呈现UI)

我想知道是否使用了太多的self.view.layoutIfNeeded()会导致这个问题吗?

我真的放弃了这个奇怪的问题,

请帮忙,

感谢。

3 个答案:

答案 0 :(得分:0)

尝试在upperViewAnimation中的第一个完成块中为UIView动画设置完成块,并继续在完成块中运行你的东西,而不是在它之外。

如果这没有帮助。尝试在viewDidLayoutSubviews中添加您的方法。 同时确保您的动画一次只能调用一次,viewDidAppear / viewDidLayoutSubviews可以多次调用,如果在动画进行过程中多次调用,则可能会冻结或变得奇怪。

您可以在动画运行时使用简单的BOOL标志检查来解决此问题,并在完成的块中完成动画时将其设置为false。

答案 1 :(得分:0)

我遇到一个问题,即在UIPropertyAnimator中调用layoutIfNeeded()导致冻结,似乎应用程序卡在了layoutIfNeeded()调用中。在DispatchQueue.main.async中包装对动画的调用最终解决了我的问题。我不完全确定发生了什么,但是我正在使用对委托方法的调用来触发动画,并且可能是动画在非主线程中开始,从而导致了奇怪的行为。无论哪种方式,对于其他人(像我一样)在这里进行谷歌搜索,请尝试将动画粘贴在main.async队列中。

答案 2 :(得分:0)

我对自动布局无法在ios13上中断感到不满意。 如果您遇到过这种情况,请找到您的好运,因为我没有指针。 就我而言,这真是好运。