Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI - Vertical Centering Content inside Scrollview

i'm trying to code a simple login page on my app. I started using SwiftUI on my newlly updated Mac OS Catalina. The Apple documentation is still lacking a lot. I need to center a VStack vertically on a Scrollview ocupying the whole page with a "limit" on it's width of 400.

Something like this:

ScrollView(.vertical) {
    VStack {
        Text("Hello World")
    }
    .frame(maxWidth: 400, alignment: .center)
}

It was easy with UIScrollView, just needed to set the ContentView to fill height and width and then centering a Vertical StackLayout inside the Content View but now with SwiftUI i just wonder..

The goal is something like this (Credit to the author)

enter image description here

If someone is wondering why i want everything inside a scrollview, it's beacause my form is quite big and i expect the user to use both landscape and portrait view so i really need the content to be scrollable, bear in mind also that in a Ipad the form doens't fill the whole screen that's why i want it centered vertically.

like image 668
nunoh123 Avatar asked Sep 26 '19 18:09

nunoh123


2 Answers

You can vertically center content in a scroll view by using GeometryReader to get the parent view's dimensions and setting the scroll view's content's minHeight to the parent's height.

When the content is too big to fit vertically it'll just scroll like normal.

For example:

var body: some View {
    GeometryReader { geometry in                    // Get the geometry
        ScrollView(.vertical) {
            VStack {
                Text("Form goes here")
                .frame(maxWidth: 400)               // Set your max width
            }
            .padding()
            .background(Color.yellow)
            .frame(width: geometry.size.width)      // Make the scroll view full-width
            .frame(minHeight: geometry.size.height) // Set the content’s min height to the parent
        }
    }
}

Preview

like image 197
Alex Robinson Avatar answered Oct 11 '22 11:10

Alex Robinson


I've build a more generic view based on @Alex answer

/// Custom vertical scroll view with centered content vertically
///
struct VScrollView<Content>: View where Content: View {
  @ViewBuilder let content: Content
  
  var body: some View {
    GeometryReader { geometry in
      ScrollView(.vertical) {
        content
          .frame(width: geometry.size.width)
          .frame(minHeight: geometry.size.height)
      }
    }
  }
}

You can use it anywhere in your app like this

  var body: some View {
    VScrollView {
      VStack {
        Text("YOUR TEXT HERE")
      }
    }
  }
like image 20
Ahmed M. Hassan Avatar answered Oct 11 '22 12:10

Ahmed M. Hassan