skip to Main Content

Whenever my code gets too big, SwiftUI starts acting weird and generates an error:

"The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions"

So I started breaking up my code into Extracted Subviews, one of the problems I came across is how to dismiss a view from a subtracted subview.

Example: we have here LoginContentView this view contains a button when the button is clicked it will show the next view UsersOnlineView.

struct LoginContentView: View {
    
    @State var showUsersOnlineView = false
    
    var body: some View {
        
        Button(action: {
            self.showUsersOnlineView = true
        }) {
            Text("Show the next view")
        }
        .fullScreenCover(isPresented: $showUsersOnlineView, content: {
            UsersOnlineView()
        })
        
    }

On the other hand, we have a button that is extracted to subview, to dismiss the modal and go back to the original view:

import SwiftUI

struct UsersOnlineView: View {
    var body: some View {
        
        ZStack {
            VStack {
                
                CloseViewButton()
                
            }
            
        }
        
    }
}

struct CloseViewButton: View {
    
    var body: some View {
        Button(action: {
            // Close the Modal
        }) {
            Text("Close the view")
        }
    }
}

2

Answers


  1. The simplest solution for this scenario is to use presentationMode environment variable:

    struct CloseViewButton: View {
        @Environment(.presentationMode) var presentationMode
        var body: some View {
            Button(action: {
                presentationMode.wrappedValue.dismiss()
            }) {
                Text("Close the view")
            }
        }
    }
    

    Tested with Xcode 12.1 / iOS 14.1

    Login or Signup to reply.
  2. Give the sbview the state property that defines if the view is shown.

    struct CloseViewButton: View {
    @Binding var showView: Bool
    
    var body: some View {
        Button(
             ShowView = false
        }) {
            Text("Close the view")
        }
    }
    

    }

    When you use the sub view give it the property

    CloseButtonView(showView: $showOnlineView)
    

    To allow the sub view to change the isShown property it needs to get a binding.

    On the presentation mode. I think this only works with Swiftui presentations like sheet and alert.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search