如果在 SwiftUI 列表中可以选择的行中选择颜色 primary 作为文本或符号图像的前景色,则在选择该行时颜色会发生变化,这将大大提高可见性。我也希望任何其他颜色都有相同的行为。
这是一个示例列表:
struct Item: Identifiable, Hashable {
var id = UUID()
var title: String
}
struct ContentView: View {
@State var listContent = [Item(title: "A"), Item(title: "B"), Item(title: "C")]
@State var selection: Item?
var body: some View {
List(selection: $selection, content: {
ForEach(listContent, id: \.self) { item in
HStack {
Text(item.title)
.foregroundStyle(.primary) //Becomes white if selected
Text(item.title)
.foregroundStyle(.red) //Stays red if selected
Text(item.title)
.foregroundStyle(selection == item ? .white : .red) //Bad experience on macOS
}
}
})
}
}
macOS 上的结果是这样的:
如您所见,我可以通过检查该行是否属于所选项目来实现所需的行为。
然而,行背景颜色在鼠标按下时发生变化,但行本身在鼠标向上时重新渲染。因此,如果我单击并按住列表,我会得到以下结果:
旧的选择仍然具有白色文本,就好像它仍然被选择一样,而真实的选择则呈现为好像没有被选择一样。一旦我释放鼠标,一切都会按预期呈现。鼠标按下和抬起之间的时间太长,可能会导致用户界面感觉缓慢且无响应。
还有其他方法可以根据背景视图更改颜色吗?我尝试过不同的混合模式,但没有成功。
搜索答案后,我发现
Label
元素在选择其封闭列表项时会应用色调。您可以使用 listItemTint
修改器更改默认颜色(未选择的颜色),如下所示:
var body: some View {
List(selection: $selection, content: {
ForEach(listContent, id: \.self) { item in
HStack {
Label { Text(item.title) } icon: { EmptyView() }
.listItemTint(Color.red) // Will change to white when selected
}
.tag(item) // Also make sure SwiftUI knows which list item is being selected
}
})
}