UIActivityIndi​​cator-开始延迟制作动画

时间:2018-10-07 11:12:37

标签: ios swift xcode uiactivityindicatorview

我正在制作一个从Web加载数据的应用程序。

加载数据通常需要0.5-1秒。

我确实使用UIActivityIndicator向用户显示正在加载数据。


现在的问题是,即使仅加载0.5-1秒,指示器也会立即启动。

有没有一种方法可以仅以2秒的延迟来开始播放动画:如果加载之前已完成,则甚至都不要开始播放。

  

目前我正在这样做:

func loadUserDetails(){

    var shouldStartActivityIndicator : Bool = true
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
        if shouldStartActivityIndicator {
            self.tableViewActivityIndicator.startAnimating()
        }
    }

    DispatchQueue.global().async {

        if GlobalSemaphores.shared.userDetails_semaphore.wait(timeout: .now()) == .timedOut { return }

        DispatchQueue.main.async {

            UserDetailsFunctions.shared.loadUserDetails(uId: self.userId) { response, userDetails in
                DispatchQueue.main.async {

                    // DO SOMETHING WITH THE DATA
                    // REMOVED THE LINES

                    self.tableViewActivityIndicator.stopAnimating()
                    shouldStartActivityIndicator = false

                    GlobalSemaphores.shared.userDetails_semaphore.signal()
                }
            }
        }
    }
}

但这很丑,我必须在各处重写。.

有没有一线解决方案?扩展吗?

编辑:

例如这样的课程?遗憾的是,这行不通。

  

EXC_BAD_ACCESS

class CustomActivityIndicatorView : UIActivityIndicatorView {

    var shouldStartActivityIndicator : Bool = false
    override func startAnimating() {
        shouldStartActivityIndicator = true
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            if self.shouldStartActivityIndicator {
                self.startAnimating()
            }
        }

    }
    override func stopAnimating() {
        shouldStartActivityIndicator = false
        self.stopAnimating()
    }
}

2 个答案:

答案 0 :(得分:0)

哦,所以我不能覆盖startAnimating() stopAnimating()函数,但是创建一个自己的函数可以做到这一点。

class CustomActivityIndicatorView : UIActivityIndicatorView {

    var shouldStartActivityIndicator : Bool = false
    func startAnimatingWithDelay () {
        shouldStartActivityIndicator = true
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            if self.shouldStartActivityIndicator {
                self.startAnimating()
            }
        }

    }
    func stopAnimatingWithDelay() {
        shouldStartActivityIndicator = false
        self.stopAnimating()

    }
}

答案 1 :(得分:0)

您当然可以使用UIActivityIndicatorView的自定义子类。我会使用asyncAfter:而不是使用不可取消的Timer

class DelayedActivityIndicatorView: UIActivityIndicatorView {

    var delay: TimeInterval = 2.0   
    private var delayTimer: Timer?

    override func startAnimating() {
        guard self.delayTimer == nil else {
            return // Return if there is already a timer running
        }

        self.delayTimer = Timer.scheduledTimer(withTimeInterval: delay, repeats: false, block: { (timer) in
            self.delayTimer = nil
            super.startAnimating()
        })

    }

    override func stopAnimating() {
        self.delayTimer?.invalidate()
        self.delayTimer = nil
        super.stopAnimating()
    }

}

您的尝试有严重错误;您被覆盖的函数称为self.startAnimating,这意味着您的函数以无限递归的方式调用自身,直到耗尽堆栈并使其崩溃为止。您需要的是super.startAnimating来调用原始函数,而不是您的替代函数。