如何在WatchOS的SwiftUI列表中设置行样式?

Dan*_*anå 6 apple-watch watchkit swiftui

我正在使用SwiftUI,正在尝试在WatchOS的列表视图中创建具有自定义.buttonStyle的按钮列表,但无法使其正常工作。目前甚至可能吗?如果可以,怎么办?

示例项目:

struct Superhero: Identifiable {
    var id = UUID()
    var name: String
}

var superheroes = [
    Superhero(name: "Batman"),
    Superhero(name: "Superman"),
    Superhero(name: "Wonder Woman"),
    Superhero(name: "Aquaman"),
    Superhero(name: "Green Lantern"),
    Superhero(name: "The Flash")
]

struct SuperheroButtonStyle: ButtonStyle {

  func makeBody(configuration: Self.Configuration) -> some View {
    configuration.label
        .frame(minWidth: 0, maxWidth: .infinity)
        .foregroundColor(.white)
        .background(configuration.isPressed ? Color.white.opacity(0.95) : .green)
        .cornerRadius(13.0)
  }
}

struct SuperHeroesView: View{
    var body: some View {
        List {

            ForEach(superheroes) { superhero in
                Button(action: {
                    print(superhero.name)
                }){
                    Text(superhero.name)
                }.buttonStyle(SuperheroButtonStyle())
           }

       }
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码产生了这个: WatchOS应用程序的图片

相反,我希望按钮看起来像这样:

所需结果的图片

在最后一个示例中,我使用的是ScrollView而不是List,这意味着在滚动列表时,行和行都不会缩小或消失。

我已经尝试过使用负填充,但这不能给我更大的拐角半径(比默认半径更大的圆角),而且看起来也不是很好。

那么,有没有一种方法可以将ButtonStyle正确地应用于List视图中的项目,包括具有自定义的cornerRadius?

还是有其他方法可以更好地控制行的外观,同时仍保留List随附的动画?

小智 8

我不知道你是否已经想通了,但我最终使用了

List {

        ForEach(superheroes) { superhero in
            Button(action: {
                print(superhero.name)
            }){
                Text(superhero.name)
            }
            .buttonStyle(SuperheroButtonStyle())
            .listRowInsets(EdgeInsets.init(top: 0, leading: 0, bottom: 0, trailing: 0))
       }

   }
Run Code Online (Sandbox Code Playgroud)

将我的按钮的边缘扩展到列表的边缘,如下所示:

具有扩展边缘的行

您还可以添加修饰符

.environment(\.defaultMinListRowHeight, 20)
Run Code Online (Sandbox Code Playgroud)

到列表本身以允许行高缩小到您想要的大小。我为这个例子选择了 20:

正确调整行高

最后有一个

.listRowPlatterColor(.clear)
Run Code Online (Sandbox Code Playgroud)

您可以使用修饰符来更改行本身的背景颜色。我在这个例子中选择了 clear 来隐藏按钮没有完全覆盖的边缘。

清盘


Mar*_*lin 6

.listRowPlatterColor(.clear)给了我我想要的。这可能比找到那个更难。

struct ContentView: View {
    @State private var EnrouteText = "Enroute"
    var body: some View {
        List {
            Button(action: {
                self.EnrouteText = getCurrentTime()
            }) {
                Text(EnrouteText)
            }
            .buttonStyle(BtnStyle(bgColor: .red, fgColor: .white))
            .listRowInsets(EdgeInsets.init(top: 0, leading: 0, bottom: 0, trailing: 0))
            .listRowPlatterColor(.clear)

            // The rest of the buttons.
        }
    }
}

// Button Styles
struct BtnStyle: ButtonStyle {
    var bgColor: Color
    var fgColor: Color

    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .frame(minWidth: 0, maxWidth: .infinity)
            .padding()
            .foregroundColor(fgColor)
            .background(bgColor)
            .cornerRadius(32)
    }
}

Run Code Online (Sandbox Code Playgroud)

使用 listRowPlatterColor 清除背景最后一部分的示例


Sen*_*ful 5

根据Human Interface Guidelines,建议滚动视图中的按钮(例如List)看起来像一个圆角矩形(而不是胶囊)。

如果您尝试使用.listRowBackground,您将得到一个尖锐的矩形(不需要):

在此处输入图片说明

如果您改为使用.listRowPlatterColor,您将获得 Apple 推荐您使用的内容(尽管如此,在一行代码中):

在此处输入图片说明

Button("Log out") {}
  .listRowPlatterColor(Color.blue)
Run Code Online (Sandbox Code Playgroud)


小智 -1

struct SuperHeroesView: View{
        var body: some View {
            List {
                ForEach(superheroes) { superhero in
                    Button(action: {
                        print(superhero.name)
                    }){
                        Text(superhero.name)
                    }.buttonStyle(SuperheroButtonStyle())
                        .listRowInsets(EdgeInsets())
                        .listRowBackground(Color.clear)
                }.environment(\.defaultMinListRowHeight, 20)

            }
        }
    }
Run Code Online (Sandbox Code Playgroud)