How To Position Views Relative To Their Top Left Corner In SwiftUI
Asked Answered
S

4

27

How do I position views relative to their top left corner in swiftUI? The "position" modifier moves the views relative to their center coordinates. So .position(x: 0, y: 0) places a views center coordinate in the top left of the screen.

I want to place a views top left coordinate in the top left of the screen, How do I do this?

struct HomeView: View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("Top Text")
                .font(.system(size: 20))
                .fontWeight(.medium)
             Text("Bottom Text")
                .font(.system(size: 12))
                .fontWeight(.regular)
        }
        .position(x: 0, y: 0)
    }
}

Currently, the left half of my view is cut off the screen, how do I prevent this? Also, how do I align relative to the safe area?

I miss UIKit πŸ˜ͺ

enter image description here

Sherronsherry answered 29/4, 2020 at 3:35 Comment(0)
B
28

@Asperi 's answer will solve the problem. But, I think we should use Spacer() rather than Color.clear and ZStack.

Spacer is specifically designed for these scenarios and makes the code easier to understand.

struct HomeView: View {
    var body: some View {
        HStack {
            VStack(alignment: .leading) {
                Text("Top Text")
                    .font(.system(size: 20))
                    .fontWeight(.medium)

                Text("Bottom Text")
                    .font(.system(size: 12))
                    .fontWeight(.regular)
                Spacer()
            }
            Spacer()
        }
    }
}

SwiftUI layout system is different from UIKit.

It asks each child view to calculate its own size based on the bounds of its parent view. Next, asks each parent to position its children within its own bounds.

https://www.hackingwithswift.com/books/ios-swiftui/how-layout-works-in-swiftui

Ballon answered 29/4, 2020 at 4:30 Comment(2)
That gets the job done! But, how would I use this technique to align other views? I'm looking for a way I can align any view similar to how the position() function works, except I'm aligning from the top left corners instead of the center. – Sherronsherry
Added more details to the answer. I suggest you read a bit about SwiftUI's layout system. I am sure that you will like it more than UIKit's frame or autolayout based positioning. – Ballon
P
9

If I correctly understand your goal the .position is not appropriate instrument for it. SwiftUI layout works better without hardcoding.

Here is possible solution. Tested with Xcode 11.4 / iOS 13.4

demo

struct HomeView: View {
    var body: some View {
        ZStack(alignment: .topLeading) {
            Color.clear
            VStack(alignment: .leading) {
                Text("Top Text")
                    .font(.system(size: 20))
                    .fontWeight(.medium)
                 Text("Bottom Text")
                    .font(.system(size: 12))
                    .fontWeight(.regular)
            }
        }.frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}
Purpura answered 29/4, 2020 at 4:13 Comment(3)
That gets the job done! But, how would I use this technique to align other views? I'm looking for a way I can align any view similar to how the position() function works, except I'm aligning from the top left corners instead of the center. – Sherronsherry
+1 for ZStack(alignment: .topLeading)! (Was getting all sort of funny stuff with H/V stacks and spacers.) – Stage
I have not get why you use Color.clear until I try it. It's inflated the z-stack! Wonderfull, never expect it – Douglass
D
5

You can use:

offset(x: CGFloat = 0, y: CGFloat = 0) -> some View

So you will be relative to current object position.

https://developer.apple.com/documentation/swiftui/gaugestyleconfiguration/currentvaluelabel-swift.struct/offset(x:y:)

Derrick answered 21/2, 2021 at 11:14 Comment(1)
If the solution is to use offset(), I think we should embed everything with GeometryReader so the calculation for offset() will be dynamic – Tanyatanzania
S
0

Frames can be stacked too.

Text("ABC")
    .frame(maxWidth: .infinity, alignment: .leading)
    .background(.red)
    .frame(height: 100, alignment: .top)
    .background(.blue)

enter image description here

Scarlett answered 20/6, 2023 at 1:56 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.