4

I am making an app that gives the user information about their speed and heading and more. For the compass/heading, I created a subview that is displayed under the speed on the main content view.

However, whenever the model/model view providing the CoreLocation information about the users speed updates, it causes the entire content view to refresh making the compass look like it is twitching.

Is there a way to make it so that changes to the observed object or state variable do not cause a subview to redraw? Below is a video of what is happening and a shortened version of my code.

struct ContentView: View {
    
    @ObservedObject var locationViewModel = LocationManager()
    @State private var showMoreInfo: Bool = false
    @State private var showingTopSpeed: Bool = false
    
    @State var showingSettingsScreen: Bool = false
    
    private var currentSpeed: String = "Your current speed is:"
    private var topSpeed: String = " Your top speed is:"
    
    var body: some View {
        VStack {
            SpeedView(speed: showingTopSpeed ? locationViewModel.userSpeed : locationViewModel.userTopSpeed)
            
            if showMoreInfo {
                Text(String(format: "With an accuracy of: +/- %.2f", locationViewModel.userSpeedAccuracy * 2.236936))
                    .animation(.easeInOut)
            }
            
            Spacer()
            
            HStack {
                CompassView()
                    .padding()
            }
            .padding()
        }
        .padding()
    }
}

Video With Issue

Here is the code from my CompassHeading class that determines the degrees of rotation on the compass. How can I prevent it form resetting to 0 each time it is redrawn?

 var objectWillChange = PassthroughSubject<Void, Never>()
    var degrees: Double = .zero {
        didSet {
            objectWillChange.send()
        }
    }
Thomas Braun
  • 1,109
  • 2
  • 13
  • 27
  • 1
    Have you tried adding conditional animations to the `CompassView`, so that the animation is set to nil when the view is redrawn? Maybe the issue is caused by the animation firing again. Making the view smaller could maybe be achieved with one of the `.padding()` modifiers. – Marco Boerner Jan 21 '21 at 00:07
  • ...Not the .padding() without parameter.. `.padding(_ instest)` or something like that? – Marco Boerner Jan 21 '21 at 00:13
  • The ObservedObject probably forces the redraw, it is pretty broad. try looking at animations for the cause or move ObservedObject use into the views that need updating, avoiding @ObservedObject in the not-to-be-redrawn view. For scaling try .scaleEffect. – Fabian Jan 21 '21 at 02:23
  • Does this answer your question https://stackoverflow.com/a/60483313/12299030? – Asperi Jan 21 '21 at 04:27
  • Try using @StateObject instead of ObservableObject and see if that makes any difference? Otherwise, maybe post the code so we can try to debug it. – nicksarno Jan 21 '21 at 05:03

0 Answers0