问题
In SwiftUI I'm noting to use a Timer that:
Try 1 - This doesn't work as get "Use of unresolved identifier 'self'"
var timer2: Timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {
self.angle = self.angle + .degrees(1)
}
Try 2 - Works, but have to put in an "_ = self.timer" to start it later
var timer: Timer {
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) {_ in
self.angle = self.angle + .degrees(1)
}
}
// then after need to use " .onAppear(perform: {_ = self.timer}) "
Is there a way to get my Try1 working? That is where in a SwiftUI file I can create the timer up front? Or actually where in SwiftUI would one normally start and stop the timer? i.e. where are lifecycle methods
Whole file:
import SwiftUI
struct ContentView : View {
@State var angle: Angle = .degrees(55)
// var timer2: Timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {
// self.angle = self.angle + .degrees(1)
// }
var timer: Timer {
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) {_ in
self.angle = self.angle + .degrees(1)
}
}
private func buttonAction() {
print("test")
self.angle = self.angle + .degrees(5)
}
var body: some View {
VStack{
Text("Start")
ZStack {
Circle()
.fill(Color.blue)
.frame(
width: .init(integerLiteral: 100),
height: .init(integerLiteral: 100)
)
Rectangle()
.fill(Color.green)
.frame(width: 20, height: 100)
// .rotationEffect(Angle(degrees: 25.0))
.rotationEffect(self.angle)
}
Button(action: self.buttonAction) {
Text("CLICK HERE")
}
Text("End")
}
.onAppear(perform: {_ = self.timer})
}
}
回答1:
It isn't clear to me that you need a timer for your example, but since there is a great deal of misinformation out there about how to include a Timer in a SwiftUI app, I'll demonstrate.
The key is to put the timer elsewhere and publish each time it fires. We can easily do this by adding a class that holds the timer as a bindable object to our environment (note that you will need to import Combine):
class TimerHolder : BindableObject {
var timer : Timer!
let didChange = PassthroughSubject<TimerHolder,Never>()
var count = 0 {
didSet {
self.didChange.send(self)
}
}
func start() {
self.timer?.invalidate()
self.count = 0
self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {
_ in
self.count += 1
}
}
}
We will need to pass an instance of this class down through the environment, so we modify the scene delegate:
window.rootViewController =
UIHostingController(rootView: ContentView())
becomes
window.rootViewController =
UIHostingController(rootView: ContentView()
.environmentObject(TimerHolder()))
Finally, lets put up some UI that starts the timer and displays the count, to prove that it is working:
struct ContentView : View {
@EnvironmentObject var timerHolder : TimerHolder
var body: some View {
VStack {
Button("Start Timer") { self.timerHolder.start() }
Text(String(self.timerHolder.count))
}
}
}
来源:https://stackoverflow.com/questions/56895459/getting-unresolved-identifier-self-in-swiftui-code-trying-to-use-timer-schedul