我需要为上一个和下一个问题创建一个动画。当前问题应该移出,下一个/上一个问题应该进来。
如果您继续单击“下一步”,它的功能会很好。
但是如果我将方向切换到上一个,
当我从上一个导航到下一个时,第一次单击总是会导致类似的差异。
为什么会这样?
import SwiftUI
struct Question {
let id: Int
let text: String
}
extension AnyTransition {
static var slideRight: AnyTransition {
let insertion = AnyTransition.move(edge: .trailing)
let removal = AnyTransition.move(edge: .leading)
return .asymmetric(insertion: insertion, removal: removal)
}
static var slideLeft: AnyTransition {
let insertion = AnyTransition.move(edge: .leading)
let removal = AnyTransition.move(edge: .trailing)
return .asymmetric(insertion: insertion, removal: removal)
}
}
enum NavigationDirection {
case forward, backward
}
struct QuizView: View {
let questions = [
Question(id: 1, text: "Qustion 1: 1"),
Question(id: 2, text: "Qustion 2: to"),
Question(id: 3, text: "Qustion 3: III"),
Question(id: 4, text: "Qustion 4: 4444"),
Question(id: 5, text: "Qustion 5: 12345"),
Question(id: 6, text: "Qustion 6: FFFFFF")
]
@State private var currentQuestionIndex = 0
@State private var navigationDirection: NavigationDirection = .forward
var body: some View {
VStack(spacing: 20) {
Text(questions[currentQuestionIndex].text)
.id(questions[currentQuestionIndex].id) // Important for transition
.transition(navigationDirection == .forward ? .slideRight : .slideLeft)
.frame(maxWidth: .infinity, maxHeight: .infinity)
HStack {
Button("Previous") {
moveToPreviousQuestion()
}
.disabled(currentQuestionIndex == 0)
Spacer()
Button("Next") {
moveToNextQuestion()
}
.disabled(currentQuestionIndex == questions.count - 1)
}
}
.padding()
.animation(.easeInOut(duration: 1.0), value: currentQuestionIndex)
}
private func moveToNextQuestion() {
if currentQuestionIndex < questions.count - 1 {
navigationDirection = .forward
currentQuestionIndex += 1
}
}
private func moveToPreviousQuestion() {
if currentQuestionIndex > 0 {
navigationDirection = .backward
currentQuestionIndex -= 1
}
}
}
当变量更新有轻微延迟时,它表现良好:
private func moveToNextQuestion() {
navigationDirection = .forward
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if currentQuestionIndex < questions.count - 1 {
currentQuestionIndex += 1
}
}
}
private func moveToPreviousQuestion() {
navigationDirection = .backward
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if currentQuestionIndex > 0 {
currentQuestionIndex -= 1
}
}
}