嵌入在 VStack 中的 HStack 中的奇怪间距行为

Posted

技术标签:

【中文标题】嵌入在 VStack 中的 HStack 中的奇怪间距行为【英文标题】:Strange spacing behaviour in HStack embedded in a VStack 【发布时间】:2021-03-18 17:31:43 【问题描述】:

我有一个 HStack 来布置一个 TextField 和一个 Button 并排在一起。我将它嵌入到VStack 中以显示下面的一行。我注意到这种情况下的垂直间距与标准的VStack 布局不同。请参阅以下屏幕截图中的详细信息。有人可以帮我理解这种行为以及我应该如何解决它?

编辑:下面的代码

import SwiftUI

struct ContentView: View 
    @State private var username: String = ""
    @State private var password: String = ""

    var body: some View 
        VStack(spacing: 8) 
        
            VStack 
                TextField("Username", text: $username)
                    .background(Color.red.opacity(0.5))
                Rectangle()
                    .fill(Color.blue)
                    .frame(height: 1)
            
            .background(Color.blue.opacity(0.5))
    
            VStack 
                HStack 
                    SecureField("Password", text: $password)
                        .background(Color.blue.opacity(0.5))
                    Button(action:  , label:  Image(systemName: "eye")     )
                
                .background(Color.red.opacity(0.5))
                Rectangle()
                    .fill(Color.blue)
                    .frame(height: 1)
            
        
        .padding()
    

【问题讨论】:

【参考方案1】:

看起来 VStack 中的默认间距可能会因内部视图而异。

如果您有 TextFieldRectangle,它的行为会有所不同;如果它是 HStackRectangle,则行为会有所不同。

我建议你添加一个明确的间距:

struct ContentView: View 
    @State private var username: String = ""
    @State private var password: String = ""

    var body: some View 
        VStack(spacing: 8) 
            VStack(spacing: 3)  // add here
                TextField("Username", text: $username)
                    .background(Color.red.opacity(0.5))
                Rectangle()
                    .fill(Color.blue)
                    .frame(height: 1)
            
            .background(Color.blue.opacity(0.5))

            VStack(spacing: 3)  // add here
                HStack 
                    SecureField("Password", text: $password)
                        .background(Color.blue.opacity(0.5))
                    Button(action: , label:  Image(systemName: "eye") )
                
                .background(Color.red.opacity(0.5))
                Rectangle()
                    .fill(Color.blue)
                    .frame(height: 1)
            
        
        .padding()
    

【讨论】:

【参考方案2】:

我认为问题在于您的编码方式,这里是一种工作方式:


import SwiftUI

struct ContentView: View 
    @State private var username: String = ""
    @State private var password: String = ""

    var body: some View 

        VStack(spacing: 8) 
        
            VStack 
                
                TextField("Username", text: $username)
                    .background(Color.red.opacity(0.5))

                Rectangle()
                    .fill(Color.blue)
                    .frame(height: 1)

            
            .background(Color.blue.opacity(0.5))
            
            VStack 

                SecureField("Password", text: $password)
                    .background(Color.blue.opacity(0.5))
                    .overlay(Button(action:  , label:  Image(systemName: "eye") ), alignment: .trailing)
 
                
                Rectangle()
                    .fill(Color.blue)
                    .frame(height: 1)
                
            
            .background(Color.red.opacity(0.5))
        
        .padding()
    


更新:

 struct ContentView: View 
    
    @State private var username: String = ""
    @State private var password: String = ""

    var body: some View 

        VStack(spacing: 8) 
        
            VStack 
                
                TextField("Username", text: $username)
                    .background(Color.red.opacity(0.5))
                    .frame(height: 20)

                Rectangle()
                    .fill(Color.blue)
                    .frame(height: 1)

            
            .background(Color.blue.opacity(0.5))
            
            VStack 
                
                HStack 
                    
                    SecureField("Password", text: $password)
                        .background(Color.blue.opacity(0.5))

                    Button(action:  , label:  Image(systemName: "eye").resizable().scaledToFit().frame(height: 20) )
  
                

                Rectangle()
                    .fill(Color.blue)
                    .frame(height: 1)
                
            
            .background(Color.red.opacity(0.5))
        
        .padding()
    

【讨论】:

我不这么认为。我特别在两个文本字段上添加了背景颜色,在我看来高度是相同的。 @Dree:我更新了代码,请再试一次!我认为没有框架问题,问题是你的编码方式。 将按钮添加为文本字段的叠加层并不是一个好主意,因为这样会在按钮下方出现很长的文本。 @Dree:然后使用我的第二次更新,它可以满足您的需求

以上是关于嵌入在 VStack 中的 HStack 中的奇怪间距行为的主要内容,如果未能解决你的问题,请参考以下文章

HStack 返回“VStack”视图

Numpy中的数组拼接、合并操作(concatenate, append, stack, hstack, vstack, r_, c_等)

如何将项目 HStack 与 VStack SwiftUI 对齐

Swiftui 将 VStack 子项高度调整为内容高度

VStack 前导对齐中的中心图像

未点击 SwiftUI 按钮