SwiftUI ForEach遍历数组时实现选中按钮前景色切换的问题解决
问题原因
你的颜色判断逻辑存在参照值匹配错误,原代码中的判断行:
.foregroundColor(self.selected == selected ? .blue: .black)
在ForEach的闭包作用域内并没有单独定义局部变量selected,编译器会把等式两边的两个selected都解析为视图持有的全局@State属性,相当于拿同一个值和自己做等值判断,结果永远为真,最终所有按钮的文本都会被设置为蓝色。
出现这个问题的核心是遍历数组时没有拿到当前按钮对应的数组索引,缺少了和全局选中状态做对比的参照对象。
修改步骤
- 调整ForEach的遍历方式,同时获取每个元素对应的索引值,作为单选判断的参照
- 修正颜色判断条件,将全局存储的选中索引,和当前循环拿到的元素索引做等值对比
- 简化点击事件的赋值逻辑,直接用当前拿到的索引更新
selected状态,省去查找数组索引的冗余操作,避免数组出现重复元素时出现索引匹配错误
修改后的完整可运行代码:
struct HorizontalCardSelector: View { @State var selected = 0 @State var items: [String] = ["Visa", "MasterCard", "PayPal"] var body: some View { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 17) { // 遍历数组时同步获取每个元素的索引 ForEach(Array(items.enumerated()), id: \.offset) { index, item in Button(action: { // 直接把当前项的索引赋值给选中状态 self.selected = index print("item \(item) tapped") }, label: { Text(item) // 仅当当前项索引和全局选中索引匹配时,显示蓝色 .foregroundColor(selected == index ? .blue: .black) .fontWeight(.semibold) }) } } } .padding(.vertical) } }
修改完成后,点击对应选项时,SwiftUI会自动触发视图刷新,只有被选中的选项文本会切换为蓝色,其余选项保持黑色,完全实现单选高亮的交互效果。
内容的提问来源于stack exchange,提问作者Mert Köksal
相关产品推荐
相关产品推荐

