Tio
Tio

Reputation: 1036

How to fix a warning `Invalid frame dimension (negative or non-finite).`

I'm currently developing an application using SwiftUI.

I'm trying to make a progress bar using a timer class.

When I make a small value like 0.05 in every parameter of Timer.publish() for a width of Rectangle I have a warning below:

Invalid frame dimension (negative or non-finite).

How could I solve this problem?


Here are the codes:

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: Version 12.0.1

iOS: 14.0

Upvotes: 5

Views: 2536

Answers (2)

VanErr
VanErr

Reputation: 21

abs() may gonna help , it works for me

Upvotes: 0

pawello2222
pawello2222

Reputation: 54601

This part can result in negative duration (e.g., when duration is 0.0001):

if self.duration > 0 {
    self.duration -= 0.05
}

Because duration is later used in:

.frame(width: CGFloat(self.duration / self.maxValue) * 150, height: 12)

you get a negative width parameter.


A solution is to make sure the duration is never below 0.

Something like:

if self.duration > 0.05 {
    self.duration -= 0.05
} else {
    self.duration = 0
}

Upvotes: 5

Related Questions