在SwiftUI的列表行中添加形状

时间:2020-07-03 14:40:57

标签: ios swiftui swiftui-list

我正在尝试创建一个列表视图,其中的行如下所示:

enter image description here

但是,我无法将Circle对准前端。在Spacer()中使用HStackVStack进行了尝试,但是它不起作用。这是我的代码及其输出。

struct PeopleView: View {
    
    let people = ["Adam", "James"]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(people, id: \.self) { person in
                    HStack {
                        Circle()
                        VStack {
                            Text("\(person)")
                        }
                    }
                }
            }
            .navigationBarTitle("People", displayMode: .inline)
        }
    }
}

tui

3 个答案:

答案 0 :(得分:4)

实际上,在这种情况下,您不需要形状本身,而只是将其视觉上呈现为圆形的蒙版即可。

因此解决方案可以像以下

demo

HStack {
    Text(person.prefix(2).uppercased()).bold()
        .foregroundColor(.white)
        .padding()
        .background(Color.red)
        .mask(Circle())          // << shaping text !!

    Spacer()
    VStack {
        Text("\(person)")
    }
}

答案 1 :(得分:2)

SwiftUI中的某些视图会填充所有可用空间。这样的视图是形状,颜色,分隔符,分隔线和GeometryReader

您的Circle是一个形状,其行为类似于Spacer(在填充空间方面)。

如果将Circle替换为圆的图像,它将起作用:

ForEach(people, id: \.self) { person in
    HStack {
        Image(systemName: "circle.fill")
            .imageScale(.large)
        Spacer()
        VStack {
            Text("\(person)")
        }
    }
}

答案 2 :(得分:0)

之所以发生这种情况,是因为您没有为Circle形状提供固定(或相对)框架,所以Circle占用了最大可用宽度。

如果添加frame(width:height:),则所有内容都应正常运行:

The expected result

struct PeopleView: View {
    
    let people = ["Adam", "James"]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(people, id: \.self) { person in
                    HStack {
                        Circle()
                            .frame(width: 50, height: 50)
                        VStack {
                            Text("\(person)")
                        }
                    }
                }
            }
            .navigationBarTitle("People", displayMode: .inline)
        }
    }
}