**我对 SwiftUi 非常陌生。我正在尝试为我的女儿创建一个应用程序,以帮助她学习如何添加。我是通过使用数轴来做到这一点的。数轴是使用水平 Divider() 线作为基础创建的,然后使用垂直分隔线来标记数轴上的每个数字。例如,如果她需要添加 4 + 8 。该应用程序将向她展示如何从 4 开始数到 8,直到达到 12。在应用程序中,这是通过 forEach 循环完成的,该循环从 4 开始一直运行到 12(例如)。每次循环迭代时,它都会生成垂直分隔符以及一个生成数字的文本字段。这是最终产品的样子**
import SwiftUI
struct GenerateNumberLineView: View {
var firstNumber: Int
var secondNumber: Int
var counter: Int
var opacityTest: Double
var body: some View {
ZStack{
Divider()
.frame(width:300, height: 4)
.overlay(.pink)
ForEach(firstNumber..<(secondNumber+firstNumber+1), id: \.self) { number in
var count = 0
let offSetter = -150 + (number-firstNumber) * 30
VStack{
Divider().frame(width:4, height: 30,
alignment: .leading)
.overlay(.pink).offset(x:CGFloat(offSetter))
Text(String("\(number)")).offset(x:CGFloat(offSetter))
}
}
}
}
}
#Preview {
GenerateNumberLineView(firstNumber: 4, secondNumber: 8,counter: 0,opacityTest: 0.0)
}
var updateTimer: Timer {
Timer.scheduledTimer(withTimeInterval: 1, repeats: true,
block: {_ in
let maximumn = num2 + numb
if self.counter == maximumn - numb{
self.updateTimer.invalidate()
}else{
self.counter += 1
}
})
}
**问题是整个数轴一次显示出来,我想将每次迭代延迟一秒钟,以便应用程序看起来像是从 4 计数到 12(例如)。我尝试将代码包装在以下调度代码的循环中 让秒 = 0.25 DispatchQueue.main.asyncAfter(截止日期: .now() + 秒){...循环内的代码}
但在引用静态方法“buildExpression”时没有完全匹配<
我最成功的是在另一个视图中调用该结构,然后实现一个计时器。 GenerateNumberLineView(firstNumber : minNum, secondaryNumber: maxNum, counter:counter,opacityTest: opacityTest).onAppear(perform: {let _ = self.updateTimer})
** 这在 76% 的情况下有效。问题是它只在屏幕上显示一个数字。它显示 4,然后 4 消失,然后显示 5。我希望它显示 4。4 停留在屏幕上,暂停一拍,然后显示 5 暂停,然后显示 6。依此类推,直到 12。所以数轴看起来像图片我已附加,但访问他们的过程已向用户显示。任何帮助将不胜感激
将您的计时器(作为发布者)放在 SwiftUI 视图中。每次计时器触发时都会增加
@State
(我们称之为 currentNumber
),直到达到 secondNumber
。
将
ForEach
的范围更改为 firstNumber..<(firstNumber + currentNumber + 1)
,现在数字会一个接一个地出现。
您可以添加
transition
和 animation
修饰符以在出现新数字时添加动画。
let firstNumber: Int
let secondNumber: Int
@State var currentNumber = 0
let timer = Timer.publish (every: 1, on: .current, in: .common).autoconnect()
var body: some View {
ZStack{
Rectangle()
.frame(width:300, height: 4)
.overlay(.pink)
ForEach(firstNumber..<(firstNumber + currentNumber + 1), id: \.self) { number in
let offSetter = -150 + (number-firstNumber) * 30
VStack{
Rectangle()
.frame(width:4, height: 30, alignment: .leading)
.overlay(.pink)
Text("\(number)")
}
.offset(x:CGFloat(offSetter))
.transition(.opacity)
}
}
.onReceive(timer) { _ in
currentNumber += 1
if currentNumber == secondNumber {
timer.upstream.connect().cancel()
}
}
.animation(.default, value: currentNumber)
}