SwiftUI - 设置视图框架

SwiftUI - setting the frame of view

当我学习像 SwiftUI (beta 6) 这样的新东西时 我想从基础做起。

我只想像在 UIKit 中一样将框架设置为子视图。 我在这里缺少什么? (这是来自模拟器)

1.子视图不在 0,0 位置。
2. 为什么至少单词的开头不在边框内?

更新: 如何在 0,0 位置设置文本视图?(就像在 UIKit 上一样)
我以为我的问题很清楚,但由于某些原因,事实并非如此。

像这样做

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

            .padding()
            Spacer()
        }
    }
}

下面是输出

如果你想删除顶部的 space 添加 .edgesIgnoringSafeArea(.top) 如下所示

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

我认为理解为什么你的解决方案不起作用很重要,因为乍一看它似乎是正确的,而且 SwiftUI 似乎以一些奇怪的方式工作(因为,当然,我们都习惯了 UIKit). 您尝试过:

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

你得到了:

首先,position修饰符表示:

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

这里有两点很重要:

  • 视图基于其中心移动,而不是基于其左上角
  • 视图在父坐标中移动space

但是文本的父级是谁? SwiftUI 中的 view modifier 是适用于 View 和 returns 的东西 View。修饰符从最后一个应用到第一个(与您如何看待它们的顺序相反)。在你的情况下:

所以:Textcentre 位于相对于 Frame 50x100 的 (0,0) 处,红色 Border.由于 VStack(这是 VStack 默认行为),生成的视图位于屏幕中央。换句话说:position 的父级(position returns a View,每个修饰符 returns a View)是 Frame 50x100 放置在屏幕中央。

如果您想将 Text 的左上角定位在 Frame 坐标 space 的 (0,0) 处,您应该使用 Spacer这样修改:

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

你会得到:

如果你想让 Frame 的左上角相对于整个 View 位于 (0,0),我认为最简单的方法是:

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

你会得到: