4

I am using .refreshable to List in Home Screen. When user clicks on any cell item from the List, presenting DetailsView by sheet/fullscreenCover. But, .refreshable is still attached with DetailsView.

How to disable refreshable in nested view (DetailsView) which is presented from Home Screen?

HomeView.swift

struct HomeView: View {
    @State private var showDetailsView: Bool = false

    var body: some View {
        NavigationView {
            List(0..<29) { _ in
                Text("Hello, world!")
                    .padding()
                    .onTapGesture {
                        showDetailsView = true
                    }
                    //.sheet or .fullScreenCover
                    .fullScreenCover(isPresented: $showDetailsView) {
                        DetailsView()
                    }
            }
            .refreshable {
                print("refreshing...")
            }
            .navigationTitle("Home")
        }
    }
}

DetailsView.swift

struct DetailsView: View {
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        NavigationView {
            List(0..<29) { _ in
                Text("DetailsView...")
                    .padding()
                }
                .navigationTitle("DetailsView")
                .navigationBarItems(
                    leading:
                        Button(action: {
                            presentationMode.wrappedValue.dismiss()
                        }) {
                            Text("Close")
                        }
                )
            }
        }
    }
}

2 Answers 2

5

Kudos to my insanely clever colleague. He's just on another level of understanding stuff.

.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil)

This will disable pull to refresh for all subviews. And you are still able to make another one if needed. Of course, quite an ugly solution, but it seems like the only one working, for now, besides moving all of the navigation modifiers outside of subviews, which is often undesirable.

UPD:

This is fixed in iOS 16.4, see the release notes

Fixed: Refreshable modifiers applied to lists will no longer also apply to lists or scroll views within the content of that list. Re-apply a refreshable modifier to the content of the list if this is desired behavior. (102052575)

Sign up to request clarification or add additional context in comments.

2 Comments

I just tried it with Xcode 14.3 and even though they say it’s fixed in the release notes I’m still having the issue.
Well, iOS 17 maybe)
1

Move fullScreenCover modifier out of NavigationView (on home), and probably in real app it will be needed to use variant with item fullScreenCover(item:) instead to pass selection.

var body: some View {
    NavigationView {
        List(0..<29) { _ in
            Text("Hello, world!")
                .padding()
                .onTapGesture {
                    showDetailsView = true
                }
                //.sheet or .fullScreenCover
        }
        .refreshable {
            print("refreshing...")
        }
        .navigationTitle("Home")
    }
    .fullScreenCover(isPresented: $showDetailsView) {   // << here !!
      DetailsView()
    }
}

Tested with Xcode 13.3 / iOS 15.4

3 Comments

Thank you, just one thing, how can I pass the selected cell item details to DetailsView?
Thanks for the hint! Might be noteworthy that this does not require a NavigationView. I wrapped my list in a Group and applied the fullScreenCover (or in my case sheet) to that instead of the list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.