user1105951
user1105951

Reputation: 2287

SwiftUI - setting the frame of view

When I learn new stuff like SwiftUI (beta 6) I want to start from the basic.

I just want to set frame to subview like in UIKit. What I'm missing here ? (this is from Simulator)

1. the subview is not in 0,0 position.
2. why at least the start of the word is not inside the border ?

enter image description here

UPDATE : how to set the text view in 0,0 position ? (just like on UIKit)
I thought my question is very clear, but for some reason, it's not.

Upvotes: 4

Views: 8540

Answers (2)

superpuccio
superpuccio

Reputation: 12972

I think it's important to understand why your solution doesn't work because at a first glance it seems correct and it seems that SwiftUI works in some weird ways (because, of course, we are all used to UIKit). You tried:

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello World")
                .position(CGPoint(x: 0, y: 0))
                .frame(width: 50, height: 100)
                .border(Color.red, width: 4)
        }
    }
}

And you got:

enter image description here

First of all, the position modifier says:

Fixes the center of the view at the specified point in its parent’s coordinate space.

Two things are important here:

  • The view is moved based on its centre, not based on its top-left corner
  • The view is moved in the parent's coordinate space

But who is the Text's parent? A view modifier in SwiftUI is something that applies to a View and returns a View. Modifiers are applied from the last one to the first one (in reverse order respect to how you see them). In your case:

enter image description here

So: The centre of the Text is positioned at (0,0) respect to a Frame 50x100 with a red Border. The resulting View is placed in the centre of the screen because of the VStack (it's the VStack default behaviour). In other words: the position's parent (position returns a View, every modifier returns a View) is the Frame 50x100 placed in the centre of the screen.

If you want to position the top-left corner of the Text at (0,0) in the Frame coordinate space you should use the Spacer modifier this way:

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello World")
            Spacer()
        }
        .frame(width: 50, height: 100)
        .border(Color.red, width: 4)
    }
}

And you'll get:

enter image description here

If you want, instead, the top-left corner of the Frame to be at (0,0) respect to the whole View I think the simplest way is:

struct ContentView: View {
    var body: some View {
        HStack {
            VStack {
                Text("Hello World")
                    .frame(width: 50, height: 100)
                    .border(Color.red, width: 4)
                Spacer()
            }
            Spacer()
        }
        .edgesIgnoringSafeArea(.all)
    }
}

And you'll get:

enter image description here

Upvotes: 15

Gagan_iOS
Gagan_iOS

Reputation: 4060

Do Like this way

struct ContentView: View {
    var body: some View {
        VStack{
            Text("Hello World")
                .frame(width: 50, height: 100)
                .border(Color.red, width: 4)

            .padding()
            Spacer()
        }
    }
}

Below is output

enter image description here

if you want to remove space on top add .edgesIgnoringSafeArea(.top) for your view like below

struct ContentView: View {
    var body: some View {
        VStack{
            Text("Hello World")
                .frame(width: 50, height: 100)
                .border(Color.red, width: 4)

            .padding()
            Spacer()
        }
        .edgesIgnoringSafeArea(.top)
    }
}

Upvotes: 0

Related Questions