我正在使用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())
}
}
}
}
此代码产生以下内容:
相反,我希望按钮看起来像这样:
在最后一个示例中,我使用的是ScrollView而不是List,这意味着在滚动列表时,行和行都没有缩小和褪色的效果。
我已经尝试过使用负填充,但这不能给我更大的拐角半径(比默认半径更大的圆角),而且看起来并不好。
那么有没有一种方法可以将ListStyle正确地应用到ButtonStyle上,包括具有自定义的cornerRadius?
或者还有其他方法可以更好地控制行的外观,同时仍保留List随附的动画?
答案 0 :(得分:5)
.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)
}
}
答案 1 :(得分:1)
我不知道您是否已经解决了这个问题,但是我最终还是使用了
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))
}
}
将按钮的边缘扩展到列表的边缘,如下所示:
您还可以添加修饰符
.environment(\.defaultMinListRowHeight, 20)
到列表本身,以允许行高缩小到所需大小。在此示例中,我选择了20:
最后有一个
.listRowPlatterColor(.clear)
修饰符,可用于更改行本身的背景色。在此示例中,我选择“清除”以隐藏按钮未完全覆盖的边缘。
答案 2 :(得分:1)
根据Human Interface Guidelines,建议滚动视图中的按钮(例如List
)看起来像是圆角矩形(而不是胶囊)。
如果您尝试使用.listRowBackground
,则会得到一个尖锐的矩形(不需要):
如果您改用.listRowPlatterColor
,则会得到Apple推荐的使用方式(尽管只是一行代码):
Button("Log out") {}
.listRowPlatterColor(Color.blue)
答案 3 :(得分:0)
我知道这不是应该实现的方式,但是看来SwiftUI中存在一个错误,阻止listRowPlatterColor
,listRowBackground
甚至listRowInsets
做任何事情在最新版本的watchOS中。
这是我现在如何解决它:
ZStack {
Color.black
MyRowView()
}
.padding(.horizontal, -8)
答案 4 :(得分:0)
要以某种颜色显示整个单元格的背景,必须使用.listRowBackground
修饰符。您可以根据自己的喜好使用Capsule
或RoundedRectangle
作为背景:
struct SuperHeroesView: View{
var body: some View {
List {
ForEach(superheroes) { superhero in
Button(action: { print(superhero.name) }){
Text(superhero.name)
} .buttonStyle(SuperheroButtonStyle())
} .listRowBackground(Capsule()
.fill(Color.green))
// or as an alternative:
//.listRowBackground(RoundedRectangle(cornerRadius: 13.0)
// .fill(Color.green))
}
}
}
您可能还想更改按钮样式,因为背景突出显示效果只会影响按钮,而不会影响整个单元格:
struct SuperheroButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.frame(minWidth: 0, maxWidth: .infinity)
.foregroundColor(configuration.isPressed ? .gray : .white)
}
}
答案 5 :(得分:-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)
}
}
}