SwiftUI HStack以相等的间距填充整个宽度

时间:2019-11-16 04:19:18

标签: ios swift swiftui

我有一个HStack:

struct BottomList: View {
    var body: some View {
        HStack() {
            ForEach(navData) { item in
                NavItem(image: item.icon, title: item.title)
            }
        }
    }
}

如何自动以相等的间距完美地居中放置其内容的整个宽度?

仅供参考,就像Bootstraps CSS类.justify-content-around

4 个答案:

答案 0 :(得分:56)

可以使用frame布局修饰符,其中.infinity参数为maxWidth,而无需其他Shape视图。

struct ContentView: View {
    var data = ["View", "V", "View Long"]

    var body: some View {
    VStack {

        // This will be as small as possible to fit the data
        HStack {
            ForEach(data, id: \.self) { item in
                Text(item)
                    .border(Color.red)
            }
        }

        // The frame modifier allows the view to expand horizontally
        HStack {
            ForEach(data, id: \.self) { item in
                Text(item)
                    .frame(maxWidth: .infinity)
                    .border(Color.red)
            }
        }
    }
    }
}

Comparison using .frame modifier

答案 1 :(得分:5)

各种*Stack类型将尝试缩小到最小尺寸以包含其子视图。如果子视图具有理想的大小,则*Stack将不会展开以填满整个屏幕。可以通过将每个孩子放在Rectangle中清晰的ZStack之上来解决此问题,因为Shape会尽可能扩展。一种方便的方法是通过View上的扩展名:

extension View {
    func inExpandingRectangle() -> some View {
        ZStack {
            Rectangle()
                .fill(Color.clear)
            self
        }
    }
}

然后您可以这样称呼它:

struct ContentView: View {
    var data = ["View", "View", "View"]

    var body: some View {
        VStack {

            // This will be as small as possible to fit the items
            HStack {
                ForEach(data, id: \.self) { item in
                    Text(item)
                        .border(Color.red)
                }
            }

            // Each item's invisible Rectangle forces it to expand
            // The .fixedSize modifier prevents expansion in the vertical direction
            HStack {
                ForEach(data, id: \.self) { item in
                    Text(item)
                        .inExpandingRectangle()
                        .fixedSize(horizontal: false, vertical: true)
                        .border(Color.red)
                }
            }

        }
    }
}

您可以根据需要调整HStack上的间距。

Non-expanding and expanding stacks

答案 2 :(得分:1)

如果项目是全角兼容的,则它将自动完成,您可以将项目包装在垫片之间以使其实现:

struct Resizable: View {
    let text: String

    var body: some View {
        HStack {
            Spacer()
            Text(text)
            Spacer()
        }
    }
}

SingleView

所以你。可以像这样在循环中使用它:

HStack {
    ForEach(data, id: \.self) { item in
        Resizable(text: item)
    }
}

MultiView

答案 3 :(得分:1)

您也可以在堆栈中使用 spacing ...即

HStack(spacing: 30){
            
            Image("NetflixLogo")
                .resizable()
                .scaledToFit()
                .frame(width: 40)
            
            Text("TV Show")
            Text("Movies")
            Text("My List")
            
        }
.frame(maxWidth: .infinity)

输出结果如下...

enter image description here