#swiftui
#swiftui
Вопрос:
У меня есть список строк, которые я хочу последовательно показывать пользователю. Например:
var array = ["Hey there!", "What's your name?"]
Чего я конкретно хочу, так это показать первую строку в течение нескольких секунд, а когда это время пройдет, показать следующую.
Вот что я сделал до сих пор:
struct ContentView: View {
@State private var array = ["Hey there!", "What's your name?"]
var body: some View {
VStack {
TimedTextView(text: array.first, numberOfVisibilitySeconds: 3, onFinishedShowing: {
self.array.removeFirst()
})
}
}
}
И вот TimedTextView
:
struct TimedTextView: View {
@State private var shouldMakeTextVisible = true
var text: String!
var numberOfVisibilitySeconds: Double!
var onFinishedShowing: (() -> Void)!
var body: some View {
VStack {
if shouldMakeTextVisible {
Text(text)
.font(.largeTitle)
.transition(.asymmetric(insertion: .opacity, removal: .opacity))
.animation(.easeIn)
.onAppear(perform: {
DispatchQueue.main.asyncAfter(deadline: .now() numberOfVisibilitySeconds) {
withAnimation {
self.shouldMakeTextVisible.toggle()
}
self.onFinishedShowing()
}
})
}
}
}
}
Как вы можете видеть, я использую замыкание, чтобы сообщить ContentView
, что Text
отображение завершено, и получить следующий. Но на самом деле происходит то, что я вижу только первую строку… Есть идеи, что я делаю не так?
Ответ №1:
Вот возможное решение:
struct TimedTextContainer: View {
@State private var currentIndex = 0
@State private var isVisible = true
let textArray: [String]
var visibilityFor: TimeInterval
var delay: TimeInterval
var body: some View {
if currentIndex < textArray.count, isVisible {
Text(textArray[currentIndex])
.font(.largeTitle)
.id(currentIndex)
.transition(.asymmetric(insertion: .opacity, removal: .opacity))
.animation(.easeIn)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() visibilityFor) {
withAnimation {
isVisible = false
}
}
DispatchQueue.main.asyncAfter(deadline: .now() visibilityFor delay) {
withAnimation {
currentIndex = 1
isVisible = true
}
}
}
}
}
}
struct ContentView: View {
let textArray = ["Hey there!", "What's your name?"]
var body: some View {
TimedTextContainer(textArray: textArray, visibilityFor: 3, delay: 1)
}
}
Комментарии:
1. Просто идеально! Спасибо!