Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwfitUI List Make Scrolling disabled

Tags:

swift

swiftui

Is there a way to make List in SwiftUI non scrollable?

like we have

tableView.isScrollEnabled

like image 275
Arslan Asim Avatar asked Nov 13 '19 11:11

Arslan Asim


People also ask

How do I stop a list from scrolling in SwiftUI?

We will use SimultaneousGesture and DragGesture to disable scrolling. We will set DragGesture's minimum distance to 0, which will disable the drag gesture to stop the scroll behavior.

How do I scroll programmatically in SwiftUI?

If you want to programmatically make SwiftUI's List move to show a specific row, you should embed it inside a ScrollViewReader . This provides a scrollTo() method on its proxy that can move to any row inside the list, just by providing its ID and optionally also an anchor.

What is scroll view in SwiftUI?

ScrollView is a view that allows for scrolling through multiple child elements/views, such as Text, Images, Stacks, etc.


2 Answers

Instead of using List which is scrollable, use ForEach.

ForEach is not scrollable by default.

Here is an example using ForEach

struct ContentView: View {
    let colors: [Color] = [.red, .green, .blue]

    var body: some View {
        VStack {
            ForEach(colors, id: \.self) { color in
                Text(color.description.capitalized)
                    .padding()
                    .background(color)
            }
        }
    }
}

A good resource for ForEach can be found here similarly one for List can be found here.


Update

There are currently two ways to stop a List from scrolling:

  • Using UITableView.appearance().isScrollEnabled = false (but this can unintended side-effects)
  • Using the 3rd party dependency Introspect

Caveats

List contained in a NavigationView

If your List is contained in a NavigationView then it will still scroll. Neither of the above methods stop it from scrolling.

Here is an example view:

import SwiftUI
import Introspect

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                ForEach(0..<10, id: \.self) { _ in
                    NavigationLink("Tap") {
                        Text("Hello").onTapGesture {
                            print("hello")
                        }
                    }
                }
            }
//            .onAppear {
//                UIScrollView.appearance().isScrollEnabled = false
//            }
//            .introspectTableView { tableView in
//                tableView.isScrollEnabled = false
//            }
        }
    }
}

Uncommenting the onAppear or the introspectTableView does not stop the List from scrolling.

List not contained in a NavigationView

If the List is not contained in a NavigationView then we can be possible to stop the List from scrolling.

If we remove the NavigationView from the above example, we can see that by uncommenting the onAppear or the introspectTableView the List does stop scrolling.

Here is a video of the above situations.

like image 150
Andrew Avatar answered Nov 15 '22 22:11

Andrew


If you need to use a List (e.g. for selection), what works best for me (instead of disabling scrolling for all Lists) is to set the height of the list programatically:

List(items){ item in Text(item.title)}.frame(
  height: CGFloat(items.count) * CGFloat(ROW_HEIGHT)
)

This way the list won't scroll since it's set to the height it needs to show all items.

like image 33
Martin Schüller Avatar answered Nov 16 '22 00:11

Martin Schüller