首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ZStack内部定位

ZStack内部定位
EN

Stack Overflow用户
提问于 2021-01-05 12:30:39
回答 2查看 6.5K关注 0票数 6

我希望这个红色矩形被重新定位到左下角,但由于某种原因,我的对齐和垫子不像我预期的那样工作。我做错了什么,怎么把它移到左下角?

代码:

代码语言:javascript
运行
复制
struct ContentView: View {
    
    var body: some View {

        ZStack {
                VStack(spacing: 0) {
                    Rectangle()
                        .fill(Color.red)
                        .frame(width: 197, height: 163)
                }
                .frame(width: 284, height: 269)
                .padding(.leading, 0)
                .padding(.bottom, 0)
                .background(Color.blue)
            }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-05 16:49:46

Yodagama的答案可能是你想要的,但也值得探究一下你的困惑,因为SwiftUI布局并不像你想的那样工作。像.frame(...)这样的调用不会“设置项的大小”,而.fill(...)也不会“设置项的颜色”。SwiftUI中的几乎所有东西都创建了一个全新的视图,负责放置它的孩子。在很多情况下,他们可能会觉得他们是一样的东西,但他们是非常不同的。

我将详细分析代码中正在发生的事情,从内部开始,然后进行工作。

代码语言:javascript
运行
复制
                Rectangle()

这将创建一个矩形,它可以填充给定的任何空间。

代码语言:javascript
运行
复制
                Rectangle()
                    .fill(Color.blue)

这嵌入了一个新视图中的矩形,该视图将环境中的“填充”颜色设置为蓝色。

代码语言:javascript
运行
复制
                Rectangle()
                    .fill(Color.blue)
                    .frame(width: 197, height: 163)

这将嵌入到具有固定大小(197x163)的新视图中。嵌入视图是居中的,但是由于矩形占用了所有可用空间,所以它填充了框架。

代码语言:javascript
运行
复制
            VStack(spacing: 0) {
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 197, height: 163)
            }

这会将该帧嵌入到一个VStack中,它在元素之间没有间隔(但这并不重要,因为只有一个)。VStack和它的孩子一样大(197x163)。

代码语言:javascript
运行
复制
            VStack(spacing: 0) {
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 197, height: 163)
            }
            .frame(width: 284, height: 269)

这将197x163 VStack集中在一个新视图中,该视图被固定为284x269。它没有将VStack的大小设置为284x269。VStacks总是和他们的孩子一样大。这是你犯了错误的具体地方(我会解释如何在完成其余部分后修复它)。

代码语言:javascript
运行
复制
            VStack(spacing: 0) {
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 197, height: 163)
            }
            .frame(width: 284, height: 269)
            .padding(.leading, 0)
            .padding(.bottom, 0)

这将创建一个新的视图,将284x269帧嵌入左边的0块额外填充(因此,这个新视图与当前框架的大小完全相同,这没有任何作用)。然后,它将其嵌入到一个新视图中,该视图在底部增加了0的额外填充。再说一遍,这一点也没有用。

代码语言:javascript
运行
复制
           VStack(spacing: 0) {
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 197, height: 163)
            }
            .frame(width: 284, height: 269)
            .padding(.leading, 0)
            .padding(.bottom, 0)
            .background(Color.blue)

这将所有这些嵌入到一个新视图中,该视图绘制的蓝色背景与嵌入式视图(284x269)大小完全相同。

代码语言:javascript
运行
复制
    ZStack {
            VStack(spacing: 0) {
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 197, height: 163)
            }
            .frame(width: 284, height: 269)
            .padding(.leading, 0)
            .padding(.bottom, 0)
            .background(Color.blue)
        }
}

最后,这一切都集中在一个ZStack中。ZStack正是包装其子程序所需的大小,所以是284x269。这一点也没有用。

那你怎么解决这个问题。您出错的地方是VStack是如何在其周围的框架中定位的。它是居中的,但你想让它对齐。这里不需要ZStack,甚至不需要VStack。你就这样做:

代码语言:javascript
运行
复制
    Rectangle()
        .fill(Color.red)
        .frame(width: 197, height: 163)
        .frame(width: 284, height: 269, alignment: .bottomLeading) // <===
        .background(Color.blue)

注意如何连续创建两个框架视图。第一个边界是矩形。第二个嵌入和对齐在一个更大的框架。这是一个很好的例子,说明了SwiftUI与开发人员想象的如此不同。实际上,这可以进一步简化,因为Color填充了它提供的所有空间,就像一个矩形:

代码语言:javascript
运行
复制
    Color.red
        .frame(width: 197, height: 163)
        .frame(width: 284, height: 269, alignment: .bottomLeading)
        .background(Color.blue)

但我经常发现,这是更好的做法,更灵活的间隔在可能的时候。根据我的经验,当你没有固定的框架尺寸时,间隔器工作得更好。(我不是说这一定是最好的实践,这只是我的经验。SwiftUI是非常新的,我们还在研究最佳实践是什么。)

代码语言:javascript
运行
复制
    VStack {
        Spacer()    // Fill all space above
        HStack {
            Rectangle()
                .fill(Color.red)
                .frame(width: 197, height: 163)
            Spacer()    // Fill all space to the right
        }
    }
    .frame(width: 284, height: 269)
    .background(Color.blue)
票数 14
EN

Stack Overflow用户

发布于 2021-01-05 13:45:38

ZStack有一个参数alignment: Alignment,它是在两个轴上对齐的。

代码语言:javascript
运行
复制
  struct ContentView: View {
        
        var body: some View {
            
            ZStack(alignment:.bottomLeading) {
                Rectangle()
                    .fill(Color.blue)
                    .frame(width: 284, height: 269)
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 197, height: 163)
            }
            
            
        }
    }
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65578978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档