В настоящее время я разрабатываю приложение с использованием SwiftUI.
Я пытаюсь сделать индикатор выполнения, используя класс таймера.
Когда я делаю небольшое значение, например 0.05 в every параметре Timer.publish() для width из Rectangle, у меня появляется предупреждение ниже:
Недопустимый размер кадра (отрицательный или неограниченный).
Как я могу решить эту проблему?
Вот коды:
TimeManager.swift
import SwiftUI
class TimeManager: ObservableObject {
var timer = Timer.publish(every: 0.05, on: .main, in: .common).autoconnect()
}
ProgressBar.swift
import SwiftUI
struct ProgressBar: View {
@EnvironmentObject var timeManager:TimeManager
@Binding var duration:Double
@Binding var maxValue:Double
var body: some View {
VStack(alignment:.leading){
RoundedRectangle(cornerRadius: 30)
.fill(Color.red)
.frame(width:CGFloat(self.duration / self.maxValue) * 150, height: 12)
Text("value:\(CGFloat(self.duration / self.maxValue) )")
}
.onReceive( self.timeManager.timer) { _ in
if self.duration > 0 {
self.duration -= 0.05
}
}
}
}
ContentView.swift
import SwiftUI
struct ContentView : View {
@State var duration:Double = 8
@State var maxValue:Double = 8
var body: some View {
ProgressBar(duration: $duration, maxValue: $maxValue)
}
}
Xcode: версия 12.0.1
IOS: 14.0
Эта часть может привести к отрицательному результату duration (например, когда duration равно 0.0001):
if self.duration > 0 {
self.duration -= 0.05
}
Потому что duration позже используется в:
.frame(width: CGFloat(self.duration / self.maxValue) * 150, height: 12)
Вы получаете отрицательный параметр ширины.
Решение состоит в том, чтобы убедиться, что duration никогда не ниже 0.
Что-то вроде:
if self.duration > 0.05 {
self.duration -= 0.05
} else {
self.duration = 0
}
@ pawello2222, Теперь все работает без каких-либо предупреждений. Спасибо за помощь!
Abs() может поможет, у меня работает
Ваш ответ может быть улучшен с помощью дополнительной вспомогательной информации. Пожалуйста, отредактируйте , чтобы добавить дополнительные сведения, такие как цитаты или документация, чтобы другие могли подтвердить правильность вашего ответа. Вы можете найти больше информации о том, как писать хорошие ответы в справочном центре.
Это не дает ответа на вопрос. Когда у вас будет достаточная репутация , вы сможете комментировать любой пост ; вместо этого давайте ответы, не требующие пояснений от спрашивающего . - Из отзыва
Я бы подумал о проверке вычитания против 0 перед вычитанием, то есть: if self.duration - 0.05 > 0. Затем вы можете добавить else, чтобы сделать продолжительность 0. Таким образом, вы не потеряете весь цикл.