Я делаю секундомер, используя SwiftUI.
Я перекрашиваю пользовательский интерфейс при изменении ориентации в целях проектирования, но это делает мой таймер недействительным. Я использовал одно из этих решений
Как мне сохранить мой таймер при изменении ориентации?
Вот модель:
class Model: ObservableObject {
@Published var isLandScape: Bool = false
@Published var isPhone: Bool = UIDevice.current.userInterfaceIdiom == .phone
@Published var isPhoneAndLandscape: Bool = false;
}
Пользовательский UIHostingController:
extension Notification.Name {
static let my_onViewWillTransition = Notification.Name("MainUIHostingController_viewWillTransition")
}
class MyUIHostingController<Content> : UIHostingController<Content> where Content : View {
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
NotificationCenter.default.post(name: .my_onViewWillTransition, object: nil, userInfo: ["size": size])
super.viewWillTransition(to: size, with: coordinator)
}
}
, который я использую в SceneDelegate:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = MyUIHostingController(rootView: HomeView().environmentObject(model))
self.window = window
window.makeKeyAndVisible()
}
}
И класс секундомера:
class StopWatch: ObservableObject {
@Published var stopWatchTime: String = "00:00:00";
@Published var isPaused = true;
var timer = Timer()
private var counter: Int = 0
func start() {
isPaused.toggle();
timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { timer in
self.counter += 1
self.stopWatchTime = StopWatch.convertCountToTimeString(counter: self.counter)
}
}
func pause() {
isPaused.toggle();
timer.invalidate()
}
func reset() {
self.timer.invalidate()
self.isPaused = true;
self.counter = 0;
self.stopWatchTime = "00:00:00"
}
}
Edit Вот как секундомер используется в представлении
struct StopWatchUI: View {
@ObservedObject var stopWatch = StopWatch()
@Binding var isSureToResetWatch: Bool;
@EnvironmentObject var model: Model
var body: some View {
return VStack {
Text(self.stopWatch.stopWatchTime)
.foregroundColor(.textPrimary)
.font(.custom("Courier",size: model.isPhoneAndLandscape ? 50 : 120))
.fontWeight(.heavy)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: nil, maxHeight: nil)
.padding(15)
.minimumScaleFactor(0.4)
.cornerRadius(5)
.lineLimit(1)
HStack {
StopWatchResetButton(isSureToResetWatch: $isSureToResetWatch, resetTime: self.stopWatch.reset)
Spacer()
StopWatchStartButton(
start: self.stopWatch.start,
pause: self.stopWatch.pause,
isStopWatchPaused: self.stopWatch.isPaused
)
}
}
}
}