Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI ScrollView only scroll in one direction

Trying to make a custom list using a view as the list row style (to get rid of the ugly line separates in the list by default).

However, once I put my ZStack rows inside a scroll view, the scroll view scrolls in both directions and not just vertically.

Here is the contentView:

NavigationView {
            ScrollView{
                VStack(alignment: .leading){
                    ForEach(friends) { friends in
                        NavigationButton(destination: MessageDetailView(friend: friends)) {
                            CustomListItem(friend: friends)
                        }
                    }
                    Spacer()
                }
            }
                .foregroundColor(.black)
                .navigationBarTitle(Text("Messages"))
        }

and here is the customListItem:

Group{
            ZStack {
                RoundedRectangle(cornerRadius: 10)
                    .shadow(radius: 1, y:1)
                    .frame(width: UIScreen.main.bounds.width - 32, height: 75)
                    .foregroundColor(.gray)

                HStack {
                    Image(systemName: "person.crop.circle")
                        .resizable()
                        .frame(width: 50, height: 50)
                    VStack(alignment: .leading) {
                        HStack {
                            Text(friend.name)
                                .font(.headline)
                            Text("\(friend.date, formatter: dateFormatter)")
                        }
                        Text(friend.messagesReceived[0])
                            .font(.subheadline)
                        }       .lineLimit(nil)
                    Spacer()
                    Image(systemName: "chevron.right.circle")
                        .foregroundColor(.black)
                    }.padding(10)
                }.padding([.leading, .trailing])
        }

Is there any way I can limit the scrolling to vertical or force a frame on this?

Trying to use the .frame(...) modifier does not work as I've tried it. This results in the view not loading at all.

Example Images:

Without ScrollView

With ScrollView wrapping the VStack

like image 612
mg_berk Avatar asked Jun 20 '19 00:06

mg_berk


3 Answers

As of Xcode 11 beta 3 (11M362v) there is an axes parameter when constructing a ScrollView which can be set to .horizontal or .vertical

ScrollView(.vertical, showsIndicators: true) { ... }
like image 155
Liam Avatar answered Oct 02 '22 05:10

Liam


This can be achieved with a GeometryReader. Wrap your ScrollView in one and then set the width of your VStack.

GeometryReader is a super easy, and pretty useful trick to have in your belt for SwiftUI :)

Here's how I got it working with your code:

NavigationView {
            GeometryReader { geometry in
                ScrollView {
                    VStack(alignment: .leading){
                        ForEach(self.friends) { friend in
                            NavigationButton(destination: MessageDetailView(friend: friend)) {
                                CustomListItem(friend: friend)
                            }
                        }
                        Spacer()
                    }.frame(width: geometry.size.width)
                }
                    .foregroundColor(.black)
                    .navigationBarTitle(Text("Messages"))
            }
        }
like image 38
piebie Avatar answered Oct 02 '22 03:10

piebie


Although in most cases the above answers works but none of them did work for me!

In my case, the problem was the scrollView children which were wider than the scrollView!

adding a static width to them did the trick.

like image 27
Ahmadreza Avatar answered Oct 02 '22 04:10

Ahmadreza