Home > Software design >  Dynamic list from TextField's data SwiftUI
Dynamic list from TextField's data SwiftUI

Time:09-03

I just started to learn Swift programing language and have a question. I'm trying to create a simple one-page application where you can add movies to a favorite list. Movies must have 2 properties: title (string, mandatory) and year (integer, mandatory). But I have a problem, I don't know how to put it in one row. And also, how to ignore duplicate movies?

import SwiftUI

struct Movie: Identifiable {
    let id = UUID()
    var title: String
}

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: {
                        self.addToList()
                    }, label: {
                        Text("Add")
                            .frame(width: 80, height: 40, alignment: .center)
                            .background(Color.blue)
                            .cornerRadius(8)
                            .foregroundColor(.white)
                    })
                    .padding()
                }
                List {
                    ForEach(model.movies) { movie in
                        MovieRow(title: movie.title)
                    }
                }
            }
            .padding()
    }
    
    func addToList() {
        guard !text.trimmingCharacters(in: .whitespaces).isEmpty else {
            return
        }
        
        guard !year.trimmingCharacters(in: .whitespaces).isEmpty else {
            return
        }
        
        let newMovie = Movie(title: text)
        model.movies.append(newMovie)
        text = ""
        
        let newYear = Movie(title: year)
        model.movies.append(newYear)
        year = ""
    }
    
}

struct MovieRow: View {
    let title: String
    
    var body: some View {
        Label (
            title: { Text(title)},
            icon: { Image(systemName: "film") }
        )
    }
}

struct DynamicList_Previews: PreviewProvider {
    static var previews: some View {
        DynamicList()
    }
}

CodePudding user response:

Maybe someone will need a similar solution, here is my result:

import SwiftUI

struct Movie: Identifiable {
    let id = UUID()
    var title: String
    var year: String
}

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: {
                    self.addToList()
                }, label: {
                    Text("Add")
                        .frame(width: 80, height: 40, alignment: .center)
                        .background(Color.blue)
                        .cornerRadius(8)
                        .foregroundColor(.white)
                })
                .padding()
            }
            List {
                ForEach(model.movies) { movie in
                    MovieRow(title: movie.title, year: movie.year)
                }
            }
        }
        .padding()
    }
    
    func addToList() {
        guard !text.trimmingCharacters(in: .whitespaces).isEmpty else {
            return
        }
        
        guard !year.trimmingCharacters(in: .whitespaces).isEmpty else {
            return
        }
        
        let newMovie = Movie(title: text, year: year)
        model.movies.append(newMovie)
        text = ""
        year = ""
    }
    
}

struct MovieRow: View {
    let title: String
    let year: String
    
    var body: some View {
        Label (
            title: { Text(title   " "   year)},
            icon: { Image(systemName: "film") }
        )
    }
}

struct DynamicList_Previews: PreviewProvider {
    static var previews: some View {
        DynamicList()
    }
}

CodePudding user response:

Try this way hope fix this issue. before appending

guard let yearValue = Int(year) , yearValue.count > 0  else { return }
  • Related