You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:18:36