Mospy
Mospy

Reputation: 31

memory leak on transitions between views in swiftUI

I have a problem. I have 4 views, the forward transition is carried out through .fullScreenCover (), on 2,3 and 4 views, I should have a back button, by pressing the transition to 1 view should occur, the problem is when I start switching between the views, it starts grow memory and in the debugger shows a lot of views, how to solve this problem? Or are there other ways to implement this? P.s view should be displayed in full screen.

FirstView

  import SwiftUI
   
  class SanityCheck0 {
     deinit {
       print("\(#file):\(#line) \(#function) Called.")
   } 
}
   
   struct FirstView: View {
     @State var isPresentable = false
     private let sany = SanityCheck0()
   
   var body: some View {
      // Text("Hello, world!").padding()
           Button("Next", action: {
               self.isPresentable.toggle()
   
           })
           .fullScreenCover(isPresented: $isPresentable) {
               SecondView()
   
           }
   }
       
   }

SecondView

import SwiftUI

class SanityCheck1 {
    deinit {
        print("\(#file):\(#line) \(#function) Called.")
    }
}

struct SecondView: View {
    @State var isPresentable = false
    @State var isPresentable1 = false
    
    private let senity = SanityCheck1()
    
    var body: some View {
        HStack(spacing: 50) {
            Button("Next", action: {
                self.isPresentable.toggle()

            })
            .fullScreenCover(isPresented: $isPresentable) {
                ThirdView()

            }
            
            Button("Back", action: {
                self.isPresentable1.toggle()

            })
            .fullScreenCover(isPresented: $isPresentable1) {
                FirstView()

            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.yellow)
        .edgesIgnoringSafeArea(.all)
        
    }
}

struct Test_Previews: PreviewProvider {
    static var previews: some View {
        SecondView()
    }
}

ThirdView

import SwiftUI

class SanityCheckk {
    deinit {
        print("\(#file):\(#line) \(#function) Called.")
    }
}

struct ThirdView: View {
    @State var isPresentable = false
    @State var isPresentable1 = false 
    
    private let sanituCheck = SanityCheckk()
    
    var body: some View {
        HStack(spacing: 50) {
            Button("Next", action: {
                self.isPresentable.toggle()

            })
            .fullScreenCover(isPresented: $isPresentable) {
                FourthView()

            }
            
            Button("Back", action: {
                self.isPresentable1.toggle()

            })
            .fullScreenCover(isPresented: $isPresentable1) {
                FirstView()

            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.green)
        .edgesIgnoringSafeArea(.all)
    }
}


struct TwoScen_Previews: PreviewProvider {
    static var previews: some View {
        ThirdView()
    }
}

FourthView

import SwiftUI

struct FourthView: View {
    @State var isPresentable = false
    @State var isPresentable1 = false
    
    var body: some View {
        HStack(spacing: 50) {
            Button("Next", action: {
                self.isPresentable.toggle()

            })
            .fullScreenCover(isPresented: $isPresentable) {
                SecondView()

            }
            
            Button("Back", action: {
                self.isPresentable1.toggle()

            })
            .fullScreenCover(isPresented: $isPresentable1) {
                FirstView()

            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.red)
        .edgesIgnoringSafeArea(.all)
    }
}

struct FourthView_Previews: PreviewProvider {
    static var previews: some View {
        FourthView()
    }
}

enter image description here

Upvotes: 0

Views: 459

Answers (1)

matt
matt

Reputation: 535890

The problem is that your Back buttons, despite the title, do not go back. When you say, for example, in SecondView,

        .fullScreenCover(isPresented: $isPresentable1) {
            FirstView()
        }

...you are not going back to the old FirstView; you are making another FirstView, a whole new and different FirstView, so that now there are two FirstViews in addition to the SecondView. You keep doing that, just making more and more new views and never going back.

The way to go back from the SecondView to the FirstView is to turn the isPresentable back on FirstView back to false:

 struct FirstView: View {
     @State var isPresentable = false // <-- this

You can do that by handing a binding to it on into SecondView. Example:

struct FirstView: View {
    @State var isPresentable = false
    var body: some View {
        Button("Next", action: {
            self.isPresentable.toggle()
        })
        .fullScreenCover(isPresented: $isPresentable) {
            SecondView(firstIsPresentable: $isPresentable)
        }
    }
}

struct SecondView: View {
    @Binding var firstIsPresentable : Bool
    var body: some View {
        Button("Back", action: {
            self.firstIsPresentable.toggle()
        })
    }
}

And so on.

Upvotes: 1

Related Questions