加载动画后仅显示按钮功能 (Swift)
Loading Animation Only Showing After Button Function (Swift)
我试图在生成新数组并将其保存到 NSUserDefaults 时显示加载动画。在如下所示的函数中调用了动画函数:
func getOrCreateCalendar(forYear: Int) -> [DetailedDate] {
if forYear == date.getDateComponents(todaysDetailDate.date).year && calendar.count > 0 {
print("forYear == today's year and the current calendar has been RETURNED FROM MEMORY")
return calendar
} else {
let existingCalendar = getExistingCalendar(forYear)
if existingCalendar != nil {
return existingCalendar!
} else {
SwiftSpinner.show("Generating new calendar for \(forYear)", animated: true)
let calendar = generateCalendarFor(forYear)
print("GENERATED NEW calendar for \(forYear)")
SwiftSpinner.show("Saving calendar", animated: false)
saveNew(calendar, year: forYear)
SwiftSpinner.hide()
return calendar
}
}
我正在使用如上所示的开源 SwiftSpinner 动画。
我在整个代码中的多个位置调用此函数(尤其是整个应用程序中的按钮)。
但是,无论何时调用此函数,动画都不会显示,直到整个过程完成。
为什么是这样?如何在生成和保存新内容时显示动画,然后在完成后将其关闭?
尝试使用以下代码在 background-queue 中执行操作:
SwiftSpinner.show("Generating new calendar for \(forYear)", animated: true)
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), {
let calendar = generateCalendarFor(forYear)
print("GENERATED NEW calendar for \(forYear)")
dispatch_async(dispatch_get_main_queue(), {
SwiftSpinner.show("Saving calendar", animated: false)
})
saveNew(calendar, year: forYear)
dispatch_async(dispatch_get_main_queue(), {
SwiftSpinner.hide()
onCompletion(calendar)
})
})
你在这里做什么:
- 你创建了一个background-queue
- 创建日历
- 从 main-queue 更新 UI (
dispatch_async(dispatch_get_main_queue(), { SwiftSpinner.show("Saving calendar", animated: false) })
(main-queue 很重要,因为 UI 只能从 main-queue)
- 保存日历(在background-queue再次)
- 调用自定义函数(这里我在 main-queue 中将其命名为
onCompletion
,它对日历做了一些事情(替换 return calendar
)
您应该确保在 dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { ... })
被调用并在 onCompletion
中再次启用之前禁用您的 UI-buttons 等,否则用户将能够在您的应用程序时按下某些按钮正在工作(并且可能更改队列使用的一些数据 -> 不好)。
为什么:
UI 是从 main-queue 更新的,但通常不会在您调用代码更新后立即更新;如果您阻止 main-queue,您的 UI 将无法更新。所以我们在 background-queue 中完成工作,这样您的 main-queue 就可以更新 UI.
详细:
您调用 dispatch_async
(来自 GrandCentralDispatch),它创建一个优先级为 QOS_CLASS_USER_INITIATED
(~正常优先级)的新队列。然后它将花括号中的代码传递给这个队列; OS 将在单独的线程中执行队列。
因为 UI 只能从 main-queue 修改,所以我们通过使用 [=16] 将更新 UI (SwiftSpinner.show("Saving calendar", animated: false)
) 的代码传递给 main-queue =] 再次。
使用completion-function是必要的,因为code/queue在后台执行并且独立于getOrCreateCalendar
;您的功能可能 returns 在队列完成并创建和保存日历之前。
我试图在生成新数组并将其保存到 NSUserDefaults 时显示加载动画。在如下所示的函数中调用了动画函数:
func getOrCreateCalendar(forYear: Int) -> [DetailedDate] {
if forYear == date.getDateComponents(todaysDetailDate.date).year && calendar.count > 0 {
print("forYear == today's year and the current calendar has been RETURNED FROM MEMORY")
return calendar
} else {
let existingCalendar = getExistingCalendar(forYear)
if existingCalendar != nil {
return existingCalendar!
} else {
SwiftSpinner.show("Generating new calendar for \(forYear)", animated: true)
let calendar = generateCalendarFor(forYear)
print("GENERATED NEW calendar for \(forYear)")
SwiftSpinner.show("Saving calendar", animated: false)
saveNew(calendar, year: forYear)
SwiftSpinner.hide()
return calendar
}
}
我正在使用如上所示的开源 SwiftSpinner 动画。 我在整个代码中的多个位置调用此函数(尤其是整个应用程序中的按钮)。
但是,无论何时调用此函数,动画都不会显示,直到整个过程完成。 为什么是这样?如何在生成和保存新内容时显示动画,然后在完成后将其关闭?
尝试使用以下代码在 background-queue 中执行操作:
SwiftSpinner.show("Generating new calendar for \(forYear)", animated: true)
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), {
let calendar = generateCalendarFor(forYear)
print("GENERATED NEW calendar for \(forYear)")
dispatch_async(dispatch_get_main_queue(), {
SwiftSpinner.show("Saving calendar", animated: false)
})
saveNew(calendar, year: forYear)
dispatch_async(dispatch_get_main_queue(), {
SwiftSpinner.hide()
onCompletion(calendar)
})
})
你在这里做什么:
- 你创建了一个background-queue
- 创建日历
- 从 main-queue 更新 UI (
dispatch_async(dispatch_get_main_queue(), { SwiftSpinner.show("Saving calendar", animated: false) })
(main-queue 很重要,因为 UI 只能从 main-queue) - 保存日历(在background-queue再次)
- 调用自定义函数(这里我在 main-queue 中将其命名为
onCompletion
,它对日历做了一些事情(替换return calendar
)
您应该确保在 dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { ... })
被调用并在 onCompletion
中再次启用之前禁用您的 UI-buttons 等,否则用户将能够在您的应用程序时按下某些按钮正在工作(并且可能更改队列使用的一些数据 -> 不好)。
为什么: UI 是从 main-queue 更新的,但通常不会在您调用代码更新后立即更新;如果您阻止 main-queue,您的 UI 将无法更新。所以我们在 background-queue 中完成工作,这样您的 main-queue 就可以更新 UI.
详细:
您调用 dispatch_async
(来自 GrandCentralDispatch),它创建一个优先级为 QOS_CLASS_USER_INITIATED
(~正常优先级)的新队列。然后它将花括号中的代码传递给这个队列; OS 将在单独的线程中执行队列。
因为 UI 只能从 main-queue 修改,所以我们通过使用 [=16] 将更新 UI (SwiftSpinner.show("Saving calendar", animated: false)
) 的代码传递给 main-queue =] 再次。
使用completion-function是必要的,因为code/queue在后台执行并且独立于getOrCreateCalendar
;您的功能可能 returns 在队列完成并创建和保存日历之前。