Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI view is in the middle instead of in the top

Tags:

ios

swift

swiftui

I'm trying to create a view in SwiftUI. In the preview, it looks like it should, but when run on my iPhone (or on the live preview) it looks like it is offset.

I tried to set the padding to -150, but then the TextField doesn't respond to touches.

VStack {
    Text("Name:")
        .padding(.bottom, 1)
    TextField($name)
        .padding(.horizontal, 25.0)
        .textFieldStyle(.roundedBorder)
        .frame(maxWidth: 500)
    Text("Image:")
        .padding(.top, 1)
    Image(uiImage: image!)
        .resizable(capInsets: EdgeInsets(), resizingMode: .stretch)
        .scaledToFit()
        .frame(width: 250, height: 250)
        .clipShape(RoundedRectangle(cornerRadius: 10))
        .padding(.top, 5)
    Button(action: {
        withAnimation {
            self.showImagePicker = true
        }
    }) {
        Text("Select Image")
            .color(.init(red: 20/255, green: 146/255, blue: 81/255))
    }
    Button(action: {
        let list = LSList( title: self.name,
                                           image: self.image!,
                                           id: 0)
        list.add()
        self.userData.listsData.append(list)
    }) {
        Text("Add List")
            .color(.white)
            .font(.system(size: 25))
            .bold()
            .padding(.horizontal, 7)
            .frame(height: 35)
            .background(Color.green)
            .clipShape(RoundedRectangle(cornerRadius: 3))
    }
    Spacer()
} .navigationBarTitle(Text("Add List"))

The view in the preview: The view in the preview

The view on my iPhone: The view on my iPhone

like image 511
Shahar Avatar asked Jun 10 '19 14:06

Shahar


People also ask

How do I start VStack at top?

If you want all your items to be at the top, just put Spacer() as the last item in VStack, and it will push all items to the top.

How do I stack views in SwiftUI?

Multiple views can be combined and embedded in stack views, which group views together. Command-click the text view to show the structured editing popover, and then choose Embed in VStack. This will embed the text views into a VStack. Also set the font of all items in the Vstack to .

What is HStack and VStack?

HStack positions views in a horizontal line, VStack positions them in a vertical line, and ZStack overlays views on top of one another.

What is VStack in Swift?

The VStack allows you to stack views vertically, from top to bottom. You can further customize the view by adding alignment or spacing to the VStack. VStack(alignment: . leading, spacing: 16) { Text("Hello, world!") .


3 Answers

I had the same issue, but found the the problem I had was in using navigationView multiple times.

I thought that we should have NavigationView in every view, but apparently, we should place navigationView only in the main view of the application, and all other views that we enter via navigationLink, automatically get the back option without the need to mention NavigationView again.

So check if you use navigationView more than once in your code.

Strangely, we can specify navigationBarTitle even in views that dont have the navigationView mentioned in them, this is because the navigationView is at the parent view. Use "displayMode: .inline", to make the navigation area as minimal as possible, it will save you real-estate.

Another thing to do, is to use Spacer(). If you want all your items to be at the top, just put Spacer() as the last item in VStack, and it will push all items to the top.

See this example:

VStack {     // What you care about displaying     Text("Something to Show 1")     Text("Something to Show 2")     Text("Something to Show 3")      // This should be the last, put everything to the top     Spacer()              } .navigationBarTitle(Text("The Title"), displayMode: .inline) 
like image 72
Guy Nir Avatar answered Sep 27 '22 22:09

Guy Nir


I had a similar issue, I wanted a VStack to align its content on the top of the screen, and was only using a NavigationView in the parent, but the VStack showed centered. What fixed it for me was using a Spacer(), like this:

    VStack(alignment: .leading, spacing: 10){         HStack(alignment: .center, spacing: 5.0) {             ...         }         Group{             ...         }         Spacer() //<-- This solved my problem    } 
like image 43
GAlonso Avatar answered Sep 28 '22 00:09

GAlonso


Assuming that your VStack is wrapped in a NavigationView, this is the reason it is not rendering correctly in the simulator. The reason it shows fine in preview is that it is not displaying the navigation bar (which includes the back button as well) because the canvas doesn’t know this view might be pushed but in runtime the navigation bar is added while you’re also using an extra NavigationView as well.

To fix it unwrap the VStack from NavigationView and simply remove this NavigationView from the child view.

like image 21
M Reza Avatar answered Sep 27 '22 22:09

M Reza