我正在尝试在SwiftUI视图中自动显示一系列图像。我可以创建一个固定的 具有预定“每个”值的计时器,并在.onReceive中触发视图更新 关闭,但我无法构造一个带有间隔属性的计时器 用户可以使用滑块对其进行调整。以下代码适用于固定 计时器。订阅会正确触发,但我似乎找不到对应的订阅 .onReceive以订阅更新图像。我也尝试创建自己的 TimerPublisher,但是我有同样的问题-如果不指定,则无法初始化 固定值。
我的观点:
struct ImageStream2: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(fetchRequest: DermPhoto.getAllDermPhotos()) var dermPhotos: FetchedResults<DermPhoto>
@State private var activeImageIndex = 0
@State private var animateSpeed: Double = 1.0
@State private var startTimer = false
let timer = Timer.publish(every: 1.0, on: .main, in: .default).autoconnect()
@State private var mst: MyTimerSubscription!
var body: some View {
GeometryReader { geo in
VStack {
Text("Time Sequence")
.foregroundColor(.blue)
.font(.system(size: 25))
Image(uiImage: UIImage(data: self.dermPhotos[self.activeImageIndex].myImage!)!)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: geo.size.width - 20, height: geo.size.width - 20, alignment: .center)
.cornerRadius(20)
.shadow(radius: 10, x: 10, y: 10)
.onReceive(self.timer) { t in
print("in fixed timer")
if self.startTimer {
self.activeImageIndex = (self.activeImageIndex + 1) % self.dermPhotos.count
}
}
Group {
HStack {
Text("0.5").foregroundColor(.blue)
Slider(value: self.$animateSpeed, in: 0.5...5.0, step: 0.5)
Text("5.0").foregroundColor(.blue)
}
.padding()
Text("Replay at: " + "\(self.animateSpeed) " + (self.animateSpeed == 1.0 ? "second" : "seconds") + " per frame")
.foregroundColor(.blue)
HStack {
Button(action: {
self.startTimer.toggle()
if self.startTimer {
self.mst = MyTimerSubscription(interval: 5.0)
} else {
self.mst.subscription.cancel()
}
}) {
ZStack {
RoundedRectangle(cornerRadius: 20)
.fill(Color.yellow)
.frame(width: 200, height: 40)
Text(self.startTimer ? "Stop" : "Start").font(.headline)
}
}
}
.padding()
}//group
}//top VStack
}.onDisappear{ self.startTimer = false }
}
}
订阅文件:
class MyTimerSubscription {
let subscription: AnyCancellable
let interval: Double
init(interval: Double) {
subscription =
Timer.publish(every:interval, on:.main, in:.default)
.autoconnect()
.sink { _ in
print("in MyTimerSubscription print")
}
self.interval = interval
}
deinit {
subscription.cancel()
}
}
任何指导将不胜感激。 Xcode 11.3(11C29)
答案 0 :(得分:0)
这似乎有点糊涂,但是我做了一个解决方案。更改计时器初始化 成为国家财产。
@State var timer = Timer.publish(every: 1.0, on: .main, in: .default).autoconnect()
然后在我用来启动图像流的按钮操作中:
self.timer = Timer.publish(every: self.animateSpeed, on: .main, in: .default).autoconnect()
然后在按钮操作中停止流:
self.timer.upstream.connect().cancel()