8

In my SwiftUI app I've a List with nested ScrollView, since I've updated my iPhone to iOS 16 the refresh on the main List has a strange behavior. It seems that every ScrollView has their own refresh. The issue is that I've applied the .refreshable modifier on the main list, not on the nested ones.

Before iOS 16 the problem did not exist. So, is a bug or we can fix it is some way?

Here is the code and a short video:

List {
    VStack(alignment: .leading) {
        Text("Line 1")
            .font(.title)
        
        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack(spacing: 20) {
                Text("Item 1")
                Text("Item 2")
                Text("Item 3")
                Text("Item 4")
                Text("Item 5")
                Text("Item 6")
                Text("Item 7")
                Text("Item 8")
                Text("Item 9")
                Text("Item 10")
            }
            .frame(height: 180)
        }
    }
    .listRowSeparator(.hidden)
    
    VStack(alignment: .leading) {
        Text("Line 2")
            .font(.title)
        
        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack(spacing: 20) {
                Text("Item 1")
                Text("Item 2")
                Text("Item 3")
                Text("Item 4")
                Text("Item 5")
                Text("Item 6")
                Text("Item 7")
                Text("Item 8")
                Text("Item 9")
                Text("Item 10")
            }
            .frame(height: 180)
        }
    }
    .listRowSeparator(.hidden)
}
.listStyle(.plain)
.refreshable {
    print("refresh!")
}

Video of the issue

1
  • It seems to be fixed in new iOS versions! Commented Jun 1, 2023 at 9:58

4 Answers 4

4
+100

If you change your List for a ScrollView, and then change the line .listStyle(.plain) for .padding(.horizontal), it will work the same with no bug.

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

4 Comments

Thanks! I hadn't thought about trying this. The only thing is that on older versions of iOS the ScrollView doesn't support .refreshable. I put an if #available (iOS 16, *), is that the best way to handle this?
.refreshable is also available on iOS 15 for ScrollView. I assume you used this version as refreshable(action:) is only available in iOS 15.0 or newer.
I've tryied on my iPad (iOS 15.7) and it doesn't work. I've read that .refreshable is available on iOS 15 for List, not for ScrollView. Apple added .refreshable on ScrollView with iOS 16.
What iPad do you have? I build and run the code with the ScrollView using refreshable(action:) on Xcode version 14.0.1 (14A400), with the iPad Pro 11-inch and iPhone 14 Pro simulators both running on iOS 15.
1

If you don't want to switch to a ScrollView from a List (because ScrollView doesn't reuse cells), using .introspectScrollView helped me. For a scrollView inside a list set isDirectionalLockEnabled to true and bounces as false to avoid this issue.

.introspectScrollView { scrollView in
     scrollView.isDirectionalLockEnabled = true
     scrollView.bounces = false
}

Comments

1

I'm assuming this is the answer you are looking for: https://stackoverflow.com/a/75834493

So on your nested List or ScrollView you'd add this modifier:

List/ScrollView {

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

Comments

0

try this on your nested ScrollViews ;)

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

Comments

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.