SwiftUI:如果在后台任务后设置,NavigationLink 不显示动画
SwiftUI: NavigationLink doesn't show animation if setting after background task
我正在尝试将新的 async/await 并发代码与 SwiftUI 视图结合使用,以便在单击按钮后加载一些基本的异步数据,以显示微调器视图,并在完成后过渡到新页面.我使用枚举来标记视图的状态,并将其与 NavigationLink 一起使用以前进到新视图。这有效,并在 'pushing' 到下一个视图之前显示 'loading' 文本视图一秒钟, 但是 在推送新视图时没有动画。这是我使用的代码:
import SwiftUI
enum ContinueActionState: Int {
case ready = 0
case showProgressView = 1
case pushToNextPage = 2
case readingError = 3
case error = 4
}
struct ContentView: View {
@State var actionState: ContinueActionState? = .ready
var body: some View {
NavigationView {
VStack {
Text("Test the Button!")
if (actionState == .showProgressView) {
ProgressView("Loading Data")
} else if (actionState == .error || actionState == .readingError) {
Text("Error in loading something")
}
else {
NavigationLink(destination: DetailPageView(), tag: .pushToNextPage, selection: $actionState) {
Button(action: {
Task {
print("on buttonClick isMain =\(Thread.isMainThread)")
self.actionState = .showProgressView
await self.startProcessingData()
//self.actionState = .pushToNextPage // animation works if only this is used
}
}) {
Text("Continue")
}
.tint(.blue)
.buttonStyle(.borderedProminent)
.buttonBorderShape(.roundedRectangle(radius: 5))
.controlSize(.large)
}
}
}.navigationTitle("Test Async")
}
}
func startProcessingData() async {
Task.detached {
print("startProcessingData isMain =\(Thread.isMainThread)")
try await Task.sleep(nanoseconds: 1_000_000_000)
//await MainActor.run {
self.actionState = .pushToNextPage
//}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct DetailPageView: View {
var body: some View {
Text("Detail page")
}
}
如果我只是放弃异步调用并在单击按钮时立即设置为 .pushToNextPage
状态,则动画效果很好。
在后台队列任务中的内容处理完成后,有什么方法可以使动画流畅地工作吗?
如果您将 NavigationLink
从 if
语句中移出,它对我来说很好用:
NavigationView {
VStack {
Text("Test the Button!")
NavigationLink(destination: DetailPageView(), tag: .pushToNextPage, selection: $actionState) { Text("") } // here
if (actionState == .showProgressView) {
ProgressView("Loading Data")
} else if (actionState == .error || actionState == .readingError) {
Text("Error in loading something")
}
else {
Button(action: {
Task {
print("on buttonClick isMain =\(Thread.isMainThread)")
self.actionState = .showProgressView
await self.startProcessingData()
}
}) {
Text("Continue")
}
.tint(.blue)
.buttonStyle(.borderedProminent)
.buttonBorderShape(.roundedRectangle(radius: 5))
.controlSize(.large)
}
}.navigationTitle("Test Async")
}
我正在尝试将新的 async/await 并发代码与 SwiftUI 视图结合使用,以便在单击按钮后加载一些基本的异步数据,以显示微调器视图,并在完成后过渡到新页面.我使用枚举来标记视图的状态,并将其与 NavigationLink 一起使用以前进到新视图。这有效,并在 'pushing' 到下一个视图之前显示 'loading' 文本视图一秒钟, 但是 在推送新视图时没有动画。这是我使用的代码:
import SwiftUI
enum ContinueActionState: Int {
case ready = 0
case showProgressView = 1
case pushToNextPage = 2
case readingError = 3
case error = 4
}
struct ContentView: View {
@State var actionState: ContinueActionState? = .ready
var body: some View {
NavigationView {
VStack {
Text("Test the Button!")
if (actionState == .showProgressView) {
ProgressView("Loading Data")
} else if (actionState == .error || actionState == .readingError) {
Text("Error in loading something")
}
else {
NavigationLink(destination: DetailPageView(), tag: .pushToNextPage, selection: $actionState) {
Button(action: {
Task {
print("on buttonClick isMain =\(Thread.isMainThread)")
self.actionState = .showProgressView
await self.startProcessingData()
//self.actionState = .pushToNextPage // animation works if only this is used
}
}) {
Text("Continue")
}
.tint(.blue)
.buttonStyle(.borderedProminent)
.buttonBorderShape(.roundedRectangle(radius: 5))
.controlSize(.large)
}
}
}.navigationTitle("Test Async")
}
}
func startProcessingData() async {
Task.detached {
print("startProcessingData isMain =\(Thread.isMainThread)")
try await Task.sleep(nanoseconds: 1_000_000_000)
//await MainActor.run {
self.actionState = .pushToNextPage
//}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct DetailPageView: View {
var body: some View {
Text("Detail page")
}
}
如果我只是放弃异步调用并在单击按钮时立即设置为 .pushToNextPage
状态,则动画效果很好。
在后台队列任务中的内容处理完成后,有什么方法可以使动画流畅地工作吗?
如果您将 NavigationLink
从 if
语句中移出,它对我来说很好用:
NavigationView {
VStack {
Text("Test the Button!")
NavigationLink(destination: DetailPageView(), tag: .pushToNextPage, selection: $actionState) { Text("") } // here
if (actionState == .showProgressView) {
ProgressView("Loading Data")
} else if (actionState == .error || actionState == .readingError) {
Text("Error in loading something")
}
else {
Button(action: {
Task {
print("on buttonClick isMain =\(Thread.isMainThread)")
self.actionState = .showProgressView
await self.startProcessingData()
}
}) {
Text("Continue")
}
.tint(.blue)
.buttonStyle(.borderedProminent)
.buttonBorderShape(.roundedRectangle(radius: 5))
.controlSize(.large)
}
}.navigationTitle("Test Async")
}