SwiftUI/iOS应用删除带交替行背景色的列表项时崩溃求助
SwiftUI列表交替行背景删除崩溃问题解决
问题
使用代码.listRowBackground((self.restaurants.firstIndex(of: restaurant)! % 2 == 0) ? Color.myLightGray: Color.white)为SwiftUI列表设置交替行背景色时,删除列表行会触发崩溃,报错:Fatal error: Unexpectedly found nil while unwrapping an Optional value。移除该行背景色代码后,删除操作可正常执行,但无法实现交替颜色效果。
原因
- 删除操作执行后,
restaurants数组元素被移除,但视图尚未完成更新,此时调用firstIndex(of: restaurant)可能返回nil,强制解包!会直接引发崩溃。 - 即使没有删除操作,
firstIndex(of:)仅返回第一个匹配元素的索引,若数组存在重复元素,会导致行背景色逻辑错误。
解决方案
直接通过ForEach的带索引遍历方式获取行索引,避免从数组中查找索引的操作:
修改后的完整代码:
List { // 改用带索引的遍历,绑定元素ID保证视图标识正确 ForEach(Array(restaurants.enumerated()), id: \.element.id) { index, restaurant in NavigationLink(value: restaurant) { VStack { HStack { let uiimage = UIImage(data: restaurant.photo) Image(uiImage: uiimage ?? UIImage(imageLiteralResourceName: "pepper")) .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: 40, maxHeight: .infinity) .clipShape(Circle()) .padding(.init(top: 0, leading: 0, bottom: 0, trailing: 0)) Text(restaurant.location) Spacer() EmojiRatingView(rating: restaurant.mainGrade) .font(.system(size: 12)) .foregroundColor(.red) } }.frame(height: 36) } // 直接使用遍历得到的index判断,无需强制解包 .listRowBackground(index % 2 == 0 ? Color.myLightGray : Color.white) }.onDelete(perform: deleteRestaurants) } func deleteRestaurants(at offsets: IndexSet) { for offset in offsets { let restaurant = restaurants[offset] modelContext.delete(restaurant) } }
说明
- 通过
enumerated()直接获取每个元素的索引,避免了数组查找操作,彻底解决nil解包崩溃问题。 - 利用
id: \.element.id确保ForEach的视图标识正确,适配SwiftUI的视图更新机制,删除操作后索引会自动同步更新,交替背景色逻辑依然准确。
内容的提问来源于stack exchange,提问作者Iggy
相关产品推荐
相关产品推荐

