如何在ForEach循环中单独缩放列表项中的图片?
解决SwiftUI List中单个状态变量控制所有项的问题
核心问题是你用了单个Bool变量selected来控制所有列表项的选中状态,导致点击任意项都会触发所有项的状态变化。下面提供两种实用的解决方案:
方案一:利用已有收藏列表判断状态(推荐)
既然你已经维护了favLists来存储收藏的country.id,完全可以直接用这个列表来判断当前项是否处于“选中/收藏”状态,不需要额外的状态变量:
// 假设你的Country模型是Identifiable的 struct Country: Identifiable { let id: String // 根据实际类型调整,比如Int // 其他属性如name等 } struct YourView: View { let countries: [Country] // 你的20个列表数据 @State private var favLists: [String] = [] var body: some View { List { ForEach(countries) { country in HStack { // 这里放你的列表项其他内容,比如国家名称 Text(country.name) Spacer() Image(systemName: favLists.contains(country.id) ? "heart.fill" : "heart") .foregroundColor(.red) .scaleEffect(favLists.contains(country.id) ? 1.5 : 1) .onTapGesture { // 点击时切换收藏状态:存在则移除,不存在则添加 if let index = favLists.firstIndex(of: country.id) { favLists.remove(at: index) } else { favLists.append(country.id) } } } } } } }
优势
- 无需额外维护状态变量,状态和收藏列表完全同步,避免数据不一致
- 代码更简洁,逻辑更直观
方案二:用字典存储单个项的状态
如果需要独立于收藏列表的临时选中状态(比如多选操作),可以用字典来记录每个country.id对应的选中状态:
struct YourView: View { let countries: [Country] @State private var selectedStates: [String: Bool] = [:] // 键是country.id,值是选中状态 @State private var favLists: [String] = [] var body: some View { List { ForEach(countries) { country in HStack { Text(country.name) Spacer() Image(systemName: "heart") .foregroundColor(.red) .scaleEffect(selectedStates[country.id, default: false] ? 1.5 : 1) .onTapGesture { // 切换当前项的选中状态 let currentState = selectedStates[country.id] ?? false selectedStates[country.id] = !currentState // 同步到收藏列表(如果需要) if !currentState { favLists.append(country.id) favLists = favLists.removingDuplicates() } else { favLists.removeAll { $0 == country.id } } } } } } } }
注意
- 字典的默认值用
default: false来处理未初始化的项 - 如果不需要和收藏列表同步,可以去掉同步逻辑
内容的提问来源于stack exchange,提问作者mrJuei3l
相关产品推荐
相关产品推荐

