4

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.

9
  • remove .poistion text will be in center Commented Aug 26, 2019 at 13:49
  • but I don't want it to be in center . I want it on 0,0 position Commented Aug 26, 2019 at 14:00
  • 1
    Then use spacer Commented Aug 26, 2019 at 14:15
  • @Fabian where to add spacer ? Commented Aug 26, 2019 at 14:31
  • Below the Text inside the VStack. Commented Aug 26, 2019 at 14:32

2 Answers 2

15

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

Sign up to request clarification or add additional context in comments.

1 Comment

This is PERFECT answer. Amazing explanation. Thank god / sun / whatever that someone finally understand exactly what I meant. This will help a lot of developers. THANK YOU !
0

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)
    }
}

3 Comments

not working well . you forgot .position(x: 0, y: 0) .
add .position(x:0, y:0) and see it's now working like UIKit
thanks for your help. I just want simple label 0,0,50,100 with simple border that will show EXACTLY like UIKit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.