SwiftUI TextField数据动态列表:电影信息同行显示与去重问题
解决SwiftUI电影收藏列表的两个问题:同行展示与重复过滤
先修正基础问题
你的代码里有两个关键错误需要先解决:
Movie结构体缺少要求的year属性addToList方法错误地把年份单独作为一个新Movie添加,这会导致标题和年份变成两个独立的列表项
问题1:同一行展示标题与年份
修改MovieRow,让它同时接收title和year参数,通过HStack把两个文本放在同一行,用Spacer可以让年份自动靠右对齐:
struct MovieRow: View { let title: String let year: Int // 新增year参数 var body: some View { Label( title: { HStack { Text(title) .font(.headline) Spacer() Text("\(year)") .font(.subheadline) .foregroundColor(.secondary) } }, icon: { Image(systemName: "film") } ) } }
问题2:实现重复电影过滤逻辑
定义重复判断标准:标题和年份完全相同的电影视为重复。在addToList方法里,先把输入的年份字符串转成Int,再检查列表中是否存在相同的电影,只有不存在时才添加:
func addToList() { // 清理输入并验证合法性 let trimmedTitle = text.trimmingCharacters(in: .whitespaces) let trimmedYearText = year.trimmingCharacters(in: .whitespaces) guard !trimmedTitle.isEmpty, let movieYear = Int(trimmedYearText) else { return // 标题为空或年份无法转成整数时不执行添加 } // 检查是否存在重复电影 let isDuplicate = model.movies.contains { existingMovie in existingMovie.title == trimmedTitle && existingMovie.year == movieYear } if !isDuplicate { let newMovie = Movie(title: trimmedTitle, year: movieYear) model.movies.append(newMovie) // 添加后清空输入框 text = "" year = "" } }
完整修正后的代码
import SwiftUI struct Movie: Identifiable { let id = UUID() var title: String var year: Int // 新增year属性 } class Model: ObservableObject { @Published var movies: [Movie] = [] } struct DynamicList: View { @StateObject var model = Model() @State var text = "" @State var year = "" var body: some View { VStack { Section { TextField("Title", text: $text) .padding() .border(.gray) TextField("Year", text: $year) .padding() .border(.gray) .keyboardType(.numberPad) Button(action: addToList) { Text("Add") .frame(width: 80, height: 40) .background(Color.blue) .cornerRadius(8) .foregroundColor(.white) } .padding() } List { ForEach(model.movies) { movie in MovieRow(title: movie.title, year: movie.year) } } } .padding() } func addToList() { let trimmedTitle = text.trimmingCharacters(in: .whitespaces) let trimmedYearText = year.trimmingCharacters(in: .whitespaces) guard !trimmedTitle.isEmpty, let movieYear = Int(trimmedYearText) else { return } let isDuplicate = model.movies.contains { $0.title == trimmedTitle && $0.year == movieYear } if !isDuplicate { model.movies.append(Movie(title: trimmedTitle, year: movieYear)) text = "" year = "" } } } struct MovieRow: View { let title: String let year: Int var body: some View { Label( title: { HStack { Text(title) Spacer() Text("\(year)") .foregroundColor(.secondary) } }, icon: { Image(systemName: "film") } ) } } // 预览 struct DynamicList_Previews: PreviewProvider { static var previews: some View { DynamicList() } }
内容的提问来源于stack exchange,提问作者NexusUA
相关产品推荐
相关产品推荐

