最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - SwiftUI's navigationBarItems leading and trailing buttons not showing in FamilyActivityPicker - Stack Overflow

programmeradmin1浏览0评论

I have the following View in SwiftUI to display FamilyActivityPicker:

import SwiftUI
import FamilyControls

struct FamilyActivityPickerView: View {
    @State private var selectionToDiscourage = FamilyActivitySelection()
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        FamilyActivityPicker(headerText: "Select Apps to Restrict", selection: $selectionToDiscourage).navigationBarItems(leading: Button("Cancel") {
            print("Cancel!")
            dismiss()
        }, trailing: Button("Done") {
            print("Done!")
            dismiss()
        }).ignoresSafeArea().onChange(of: selectionToDiscourage) { newSelection in
            let applications = selectionToDiscourage.applications
            let categories = selectionToDiscourage.categories
            let webDomains = selectionToDiscourage.webDomains
            print("applications: \(applications), categories: \(categories), webDomains: \(webDomains)")
        }
    }
}

However, neither of the navigationBarItems leading and trailing buttons are showing:

What am I doing wrong? How are we supposed to Cancel or Done the FamilyActivityPicker view?

EDIT:

When I use NavigationStack with .toolbar, I end up with 2 navigation bars as shown below screenshot which looks very ugly and wastes space:

import SwiftUI
import FamilyControls

struct FamilyActivityPickerView: View {
    @State private var selectionToDiscourage = FamilyActivitySelection()
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        NavigationStack {
            FamilyActivityPicker(selection: $selectionToDiscourage).ignoresSafeArea().onChange(of: selectionToDiscourage) { newSelection in
                let applications = selectionToDiscourage.applications
                let categories = selectionToDiscourage.categories
                let webDomains = selectionToDiscourage.webDomains
                print("applications: \(applications), categories: \(categories), webDomains: \(webDomains)")
            }.toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("Cancel") {
                        print("Cancel!")
                        dismiss()
                    }
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Done") {
                        print("Done!")
                        dismiss()
                    }
                }
            }
        }
    }
}

Result:

I have the following View in SwiftUI to display FamilyActivityPicker:

import SwiftUI
import FamilyControls

struct FamilyActivityPickerView: View {
    @State private var selectionToDiscourage = FamilyActivitySelection()
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        FamilyActivityPicker(headerText: "Select Apps to Restrict", selection: $selectionToDiscourage).navigationBarItems(leading: Button("Cancel") {
            print("Cancel!")
            dismiss()
        }, trailing: Button("Done") {
            print("Done!")
            dismiss()
        }).ignoresSafeArea().onChange(of: selectionToDiscourage) { newSelection in
            let applications = selectionToDiscourage.applications
            let categories = selectionToDiscourage.categories
            let webDomains = selectionToDiscourage.webDomains
            print("applications: \(applications), categories: \(categories), webDomains: \(webDomains)")
        }
    }
}

However, neither of the navigationBarItems leading and trailing buttons are showing:

What am I doing wrong? How are we supposed to Cancel or Done the FamilyActivityPicker view?

EDIT:

When I use NavigationStack with .toolbar, I end up with 2 navigation bars as shown below screenshot which looks very ugly and wastes space:

import SwiftUI
import FamilyControls

struct FamilyActivityPickerView: View {
    @State private var selectionToDiscourage = FamilyActivitySelection()
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        NavigationStack {
            FamilyActivityPicker(selection: $selectionToDiscourage).ignoresSafeArea().onChange(of: selectionToDiscourage) { newSelection in
                let applications = selectionToDiscourage.applications
                let categories = selectionToDiscourage.categories
                let webDomains = selectionToDiscourage.webDomains
                print("applications: \(applications), categories: \(categories), webDomains: \(webDomains)")
            }.toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("Cancel") {
                        print("Cancel!")
                        dismiss()
                    }
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Done") {
                        print("Done!")
                        dismiss()
                    }
                }
            }
        }
    }
}

Result:

Share edited Mar 8 at 22:44 sudoExclamationExclamation asked Mar 8 at 21:30 sudoExclamationExclamationsudoExclamationExclamation 8,81810 gold badges51 silver badges120 bronze badges 4
  • I don't have a NavigationStack as parent container because the FamilyActivityPicker has its own navigation bar, so I thought I didn't need one. When I add a NavigationStack as parent container, I end up having 2 navigation bars, one mine and one provided by the FamilyActivityPicker. Is there a way to avoid that? – sudoExclamationExclamation Commented Mar 8 at 22:14
  • I don't think I can "drop the NavigationStack that is inside FamilyActivityPicker" because the FamilyActivityPicker is provided by Apple. I can't make changes to it as it's closed source. – sudoExclamationExclamation Commented Mar 8 at 22:31
  • @BenzyNeez I edited by question with result of using NavigationStack with .toolbar, I end up with 2 navigation bars as shown below screenshot which looks very ugly and wastes space. Any way to fix it? – sudoExclamationExclamation Commented Mar 8 at 22:44
  • I actually tried using overlays with ZStack containing the buttons. But it becomes an issue as soon as the user clicks the searchbar as iOS animates the searchbar to the top and it ends up behind my buttons. Can you explain what do you mean by showing the picker as a sheet? – sudoExclamationExclamation Commented Mar 8 at 23:15
Add a comment  | 

2 Answers 2

Reset to default 1

What you are looking for is `familyActivityPicker` not `FamilyActivityPicker`

    import SwiftUI
    import FamilyControls

    struct FamilyParentView: View {
        @State var selection = FamilyActivitySelection()
        @State var isPresented = false


       var body: some View {
           Button("Present FamilyActivityPicker") { isPresented = true }
           .familyActivityPicker(isPresented: $isPresented,
                                 selection: $selection)
           .onChange(of: selection) { _, newSelection in
               let applications = selection.applications
               let categories = selection.categories
               let webDomains = selection.webDomains
           }
       }
    }

You cannot modify the navigation buttons of the FamilyActivityPicker.

It looks like you are presenting your FamilyActivityPickerView in a sheet. if that is the case, you should use the .familyActivityPicker modifier, instead of the view FamilyActivityPicker. Replace the .sheet modifier with this modifier.

Change

.sheet(isPresented: $isPresened) {
    FamilyActivityPickerView()
}

to

.familyActivityPicker(isPresented: $isPresented, selection: $selection)

SwiftUI will present a FamilyActivityPicker in a sheet, and it will automatically add "Done" and "Cancel" buttons.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论