我有一个 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
可以使用
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)
}
}
}
}
}
...但对于最后一个项目,不要
添加
Spacer()
:
Spacer()
即使项目宽度不同,间隔均匀的示例列表:
struct BottomList: View {
var body: some View {
HStack() {
ForEach(data) { item in
Item(title: item.title)
if item != data.last { // match everything but the last
Spacer()
}
}
}
}
}
并不适用于所有情况:当涉及到具有不同宽度的项目时,它对我不起作用)
各种
*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(spacing: 30){
Image("NetflixLogo")
.resizable()
.scaledToFit()
.frame(width: 40)
Text("TV Show")
Text("Movies")
Text("My List")
}
.frame(maxWidth: .infinity)
我对接受的答案不满意,因为它们在
struct EvenlySpacedHStack: View {
let items: [Int] = [1,2,3]
var body: some View {
ZStack() {
Capsule().foregroundColor(.yellow)
HStack() {
ForEach(Array(items.enumerated()), id: \.element) { index, element in
switch index {
case items.count - 1:
Image(systemName: "\(element).circle.fill")
.resizable()
.aspectRatio(1.0, contentMode: .fit)
default:
Image(systemName: "\(element).circle.fill")
.resizable()
.aspectRatio(1.0, contentMode: .fit)
Spacer()
}
}
}
.padding(8)
}
.frame(height: 55)
}
}
当元素和
space-between
没有足够的空间时,在元素之间仅使用普通的 Spacer
可能会导致元素和文本在较小的容器中收缩和截断,因为
Spacers
还需要一些空间空间量。
所提供答案的结果可能如下所示:但是,您可以通过将
Spacer
minimumWidth
Spacers
来解决此问题,如下所示:layoutPriority
通过这种技术,无论容器大小如何,您都可以为视图实现真正的水平
struct SpaceBetweenView: View {
var body: some View {
HStack(spacing: 0) {
ForEach(0..<6, id: \.self) { item in
if item != 0 {
Spacer()
// Set the minWidth to 0 so the Spacer can shrink to 0 width
// and doesn't block any space required for the Text view below.
.frame(minWidth: 0) // <--
}
Text("Item \(item)")
.lineLimit(1)
.background(Color.green)
// Use a higher layoutPriority for the desired view to prevent it from shrinking
// when there is not enough space in the container
// for both (the Spacers and the elements).
.layoutPriority(1) // <--
}
}
.frame(width: 300, height: 200)
.border(Color.black)
}
}
#Preview {
SpaceBetweenView()
}
行为。文本元素将不再因使用
space-between
而被截断,并且仅在存在时才会截断没有足够的空间容纳元素本身。
结果
在 Xcode 15.2、Swift 5、iOS 16.6 上测试
您只需为每个元素添加
.frame(maxWidth: .infinity)