iOS Development

ios – SwiftUI: dismissing `ActionSheet` or `sheet` dismisses its mother or father view

Spread the love


I’ve a view FooView in a navigation stack introduced through a NavigationLink.

Now FooView has a button that can set off a ActionSheet:

struct FooView: View {
    @State non-public var showActions = false

    var physique: some View {

<snip>

            Button(motion: {
                showActions = true
            }) {
                Picture(systemName: "arrow.up.circle")
            }
            .actionSheet(isPresented: $showActions) {
                ActionSheet(title: Textual content("Actions"),
                            message: nil,
                            buttons: [
                                .default(Text("Option 1")) {
                                    // TODO
                                },
                                .default(Text("Option 2")) {
                                    // TODO
                                },
                                .cancel()
                            ])
            }

The issue is: when the ActionSheet is dismissed (both cancelled or chosen possibility), its mother or father view, i.e. FooView can be dismissed, i.e. pops up from the navigation stack.

Is there a strategy to forestall it doing that?

Extra importantly, why is that this occurring? What triggers FooView going away?

iOS model: iOS 15 on iPhone

XCode: 14.2

EDIT:

Here’s a minimal reproducible code:

import SwiftUI

@fundamental
struct ViewDismissApp: App {
    var physique: some Scene {
        WindowGroup {
            NavigationView {
                TabView {
                    ContentView(title: "Tab 1")
                        .tabItem {
                            Label("Tab1", systemImage: "wifi")
                        }
                    ContentView(title: "Tab 2")
                        .tabItem {
                            Label("Tab2", systemImage: "wrench.adjustable")
                        }
                }
            }
            .navigationViewStyle(.stack)
        }
    }
}


struct ContentView: View {
    let title: String

    var physique: some View {
        VStack {
            NavigationLink {
                FooView()
            } label: {
                Textual content(title)
            }
        }
    }
}

struct FooView: View {
    @State non-public var showActions = false

    var physique: some View {
        VStack {
            Textual content("Foo View")
            
            actionButton()
        }
    }
    
    non-public func actionButton() -> some View {
        Button(motion: {
            showActions = true
        }) {
            Picture(systemName: "arrow.up.circle")
        }
        .actionSheet(isPresented: $showActions) {
            ActionSheet(title: Textual content("Actions"),
                        message: nil,
                        buttons: [
                            .default(Text("Option 1")) {
                                // TODO
                            },
                            .default(Text("Option 2")) {
                                // TODO
                            },
                            .cancel()
                        ])
        }
    }
}

When creating this pattern mission, it appears to me that having TabView inside NavigationView is expounded to this downside. However I nonetheless do not know why.

Leave a Reply

Your email address will not be published. Required fields are marked *