我正在制作一个从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()
}
}
答案 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
来调用原始函数,而不是您的替代函数。