3

I am working on a SwiftUI app, and I have a NavigationView with some buttons in the navigation bar. The problem is that after dismissing a full-page sheet (triggered by a button, not in the navigation bar), those buttons stop working.

I've tried the following, but some TestFlight users say the problem persists (I can't reproduce it myself):

  1. Add an id to each button and change it after the dismiss (I even added it to the toolbar) to force a repaint
  2. Add a height to buttons and navbar
  3. Add @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> to the presenting and presented views
  4. Set the navigation bar title display mode to inline

I saw an answer on a similar post suggesting wrapping the navigation in a UINavigation. But how do you go about that? I have wrapped views (UITextView), but do you need to wrap the controller? or the navigationItem? or just the buttons. The answer didn't elaborate.

It only seems to happen when the sheet is presented by a button outside the navigation bar. The buttons in the navigation bar also present sheets and they cause no issues. I'm tempted to just hide the navbar altogether and fake it with a regular view.

Just in case you want to see what I have, here's the relevant code in my presenting view (I removed some unrelated content and functionality):

struct PListView: View {
//https://stackoverflow.com/questions/58837007/multiple-sheetispresented-doesnt-work-in-swiftui
enum ActiveSheetProjectList: Identifiable {
    case help, settings
    
    var id: Int {
        hashValue
    }
}

enum ActiveFullSheetProjectList: Identifiable {
    case addProject, quickCount
    
    var id: Int {
        hashValue
    }
}

@ObservedObject var viewModel : ProjectListViewModel
@State var presentingDeleteProjectSheet = false
@State var itemsToDelete : [UUID]?
@State var activeSheet: ActiveSheetProjectList?
@State var activeFullSheet : ActiveFullSheetProjectList?
@ObservedObject var settings : Settings
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
 
init(settings: Settings) {
    self.viewModel = ProjectListViewModel()
    self.settings = settings
    //https://medium.com/@francisco.gindre/customizing-swiftui-navigation-bar-8369d42b8805
    // this is not the same as manipulating the proxy directly
    let appearance = UINavigationBarAppearance()
    
    // this overrides everything you have set up earlier.
    appearance.configureWithTransparentBackground()
    appearance.backgroundColor = UIColor(Color.navBar)
    
    // this only applies to big titles
    appearance.largeTitleTextAttributes = [
        .font : UIFont.systemFont(ofSize: 20),
        NSAttributedString.Key.foregroundColor : UIColor(Color.smallTextMain)
    ]
    // this only applies to small titles
    appearance.titleTextAttributes = [
        .font : UIFont.systemFont(ofSize: 20),
        NSAttributedString.Key.foregroundColor : UIColor(Color.smallTextMain)
    ]
    
    //In the following two lines you make sure that you apply the style for good
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
    UINavigationBar.appearance().standardAppearance = appearance
    
    // This property is not present on the UINavigationBarAppearance
    // object for some reason and you have to leave it til the end
    UINavigationBar.appearance().tintColor = UIColor(Color.smallTextMain)

   
}

var body: some View {

 NavigationView {
        
        ZStack {
            Color.background.edgesIgnoringSafeArea(.all)
            
            VStack {
                
                 List {
                            
                            ForEach(projects) { project in
                                
                                NavigationLink(destination: ProjectView(project: project, settings: settings, viewModel: ProjectListViewModel(), viewContext: viewContext)
                                                .environmentObject(self.settings)
                                                
                                {
                                    HStack {
                                        Text(project.name ?? "").font(.headline).padding(.bottom, 5).padding(.top, 5)
                                        
                                    }
                                }
                                .listRowInsets(.init(top: 10, leading: 3, bottom: 10, trailing: 3))
                                .accessibilityHint(Text(NSLocalizedString("View project details", comment: "")))
                                
                            }
                            .onDelete(perform: { indexSet in
                                presentingDeleteProjectSheet = true
                                itemsToDelete = indexSet.map { projects[$0].id! }
                                
                            })
                            
                            .listRowBackground(Color.lightGray)
                            .padding(0)
                            .actionSheet(isPresented: $presentingDeleteProjectSheet) {
                                var name = NSLocalizedString("Project", comment: "Generic label")
                                if let id = itemsToDelete?.first {
                                    name = projects.first(where: {$0.id == id})?.name ?? ""
                                }
                                return ActionSheet(title: Text(NSLocalizedString(String.localizedStringWithFormat("Delete %@", name), comment: "alert title")), message: Text(NSLocalizedString("Deleting a project can't be undone", comment: "Deleting alert message")), buttons: [
                                    .destructive(Text(NSLocalizedString("Delete", comment: "Button label"))) {
                                        if itemsToDelete != nil {
                                            viewModel.deleteProjects(projects: activeProjectsDateCreated, ids: itemsToDelete!)
                                            
                                        }
                                    },
                                    .cancel({itemsToDelete?.removeAll()})
                                ])
                            }
                        }
                        .padding(0)
                        .onAppear(perform: {
                            UITableView.appearance().backgroundColor = UIColor(Color.lightGray)
                            UITableViewCell.appearance().selectionStyle = .none
                        })
                        
                    }
                    
                } 
            }
            .fullScreenCover(item: $activeFullSheet, content: { item in
                switch item {
                case .quickCount :
                
                // THIS IS THE SHEET THAT CAUSES THE ISSUES
                    QuickCountView(viewModel: CounterViewModel(counter: viewModel.getScratchCounter(projects: quickCountProject), sound: settings.sound, showTotal: settings.showTotal, viewContext: viewContext))
                                            .environmentObject(settings)
                case .addProject:
                    // No problems after dismissing this one
                    AddEditProjectView(viewModel: AddEditProjectViewModel(project : nil,  startAt: settings.startNumber, viewContext: viewContext), isNew: true, isEditing: .constant(true))
                                                .environmentObject(settings)
                }
            })      
                
            Button(action: { activeFullSheet = .quickCount }, label: {
                Text(NSLocalizedString("Quick Count +", comment: "Button label"))
                    .accessibilityLabel(NSLocalizedString("Quick count", comment: ""))
            })
            .buttonStyle(CustomButton(style: .button, size: .large))
            .padding()
            .sheet(item: $activeSheet) { item in
                switch item {
                case .help:
                    HelpView()
                case .settings:
                    SettingsView()
                        .environmentObject(settings)
                }

            }
        }
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItemGroup(placement: .navigationBarLeading) {
                HStack {
                    Button(action: {
                        self.activeSheet = .settings
                    }) {
                        Image(systemName: "gearshape.fill")
                            .font(Font.system(size: 28, weight: .medium, design: .rounded))
                            .foregroundColor(Color.main)
                            .accessibilityLabel(Text(NSLocalizedString("Settings", comment: "a11y label")))
                            .frame(height: 96, alignment: .trailing)
                    }
                    Button(action: {
                        self.activeSheet = .help
                    }) {
                        Image(systemName: "questionmark")
                            .font(Font.system(size: 28, weight: .semibold, design: .rounded))
                            .foregroundColor(Color.main)
                            .accessibilityLabel(Text(NSLocalizedString("Help", comment: "a11y label")))
                            .frame(height: 96, alignment: .trailing)
                    }
                }
            }

            ToolbarItemGroup(placement: .navigationBarTrailing) {
                HStack {
                    Button(action: { activeFullSheet = .addProject }) {
                        Image(systemName: "plus")
                            .font(Font.system(size: 30, weight: .semibold))
                            .foregroundColor(Color.main)
                            .accessibilityLabel(Text(NSLocalizedString("Add a Project", comment: "a11y label")))
                            .frame(height: 96, alignment: .trailing)
                    }
                    Button(action: {
                        self.isEditing.toggle()
                    }) {
                        Image(systemName: isEditing ? "xmark" : "pencil")
                            .font(Font.system(size: 28, weight: .black))
                            .foregroundColor(activeProjectsDateCreated.count >= 1 ? Color.main : Color.gray)
                            .accessibilityLabel(Text(NSLocalizedString("Edit Project List", comment: "a11y label")))
                            .frame(height: 96, alignment: .trailing)
                        
                    }.disabled(activeProjectsDateCreated.count < 1)
                    
                    .frame(height: 96, alignment: .trailing)
                    
                }
            }
        }
    }
    
}

 
coopersita
  • 5,011
  • 3
  • 27
  • 48

0 Answers0