Home > Net >  Broken Binding and ObservedObject in SwiftUI
Broken Binding and ObservedObject in SwiftUI

Time:01-23

I have a structure where at the end of AddTaskView_Preview: ..... there is { task in } in AddTaskView, exactly like this:

 struct AddTaskView_Previews: PreviewProvider {
     static var previews: some View {
         AddTaskView{task in }, formVM: ToDoFormViewModel())
             .environmentObject(DataStore())
     }
}

This type does not allow the use of @Binding or @ObservedObject - formVM: ToDoFormViewModel() in my application, because the two values Binding and ObservedObject work for me in other views only with parentheses of type () and not { }!

What about that please? I normally have this code in my views:

ContentView(viewRouter: ViewRouter(), formVM: ToDoFormViewModel()) , but it doesn't fit inside the square brackets { } with { task in } in the above example.

How should I consume my ObservedObject in formVM: ToDoFormViewModel() with those { } ?

CodePudding user response:

It's basically from this tutorial Calendar with adding an event.

" https://www.youtube.com/watch?v=aTSjMpgkXkY&t=1226s "

My idea is to add sports activities to your calendar and on another view (Tab Home) display the total mileage (total) kilometers per day, week, month, year in the panels. Nothing more. Thank you for your valuable knowledge and help.

CodePudding user response:

I would have the whole code of the file here:

    import SwiftUI

struct AddTaskView: View {

    /// - Callback
    var onAdd: (Task)->()
    /// - View Properties
    @Environment(\.dismiss) private var dismiss
    @State private var taskName: String = ""
    @State private var taskLenght: String = ""
    @State private var taskTime: String = ""
    @State private var taskDescription: String = ""
    @State private var taskDate: Date = .init()
    @State private var taskCategory: Category = .general
    /// - Category Animation Properties
    @State private var animateColor: Color = Category.general.color
    @State private var animate: Bool = false
    @State private var textActivity = ""
    @EnvironmentObject var dataStore: DataStore
    @ObservedObject var formVM: ToDoFormViewModel
    @Binding var textActivity: String

    var body: some View {
        VStack(alignment: .leading) {
            VStack(alignment: .leading, spacing: 10) {
                Button {
                    dismiss()
                } label: {
                    Image(systemName: "chevron.left")
                        .foregroundColor(.white)
                        .contentShape(Rectangle())
                }
                VStack(alignment: .leading){
                
                Text(“Create a new activity“)
                    .ubuntu(28, .light)
                    .foregroundColor(.white)
                    .padding(.vertical,15)
                    
                    
                TitleView(“NAME“)
                
                TextField(“NEW ACTIVITY“, text: $taskName)
                    .ubuntu(16, .regular)
                    .tint(.white)
                    .foregroundColor(.white)
                    .padding()
                    .background(RoundedRectangle(cornerRadius: 80).fill(Color.black.opacity(0.1)))
                    .foregroundColor(.black)
                    .offset(x: -4, y: -2)
                    
                Rectangle()
                    .fill(.white.opacity(0.7))
                    .frame(height: 1)
                    
                    
                TitleView(“DISTANCE“)
                
                TextField("Délka závodu (km)", text: $taskLenght)
                    .ubuntu(16, .regular)
                    .tint(.white)
                    .foregroundColor(.white)
                    .padding()
                    .background(RoundedRectangle(cornerRadius: 80).fill(Color.black.opacity(0.1)))
                    .foregroundColor(.black)
                    .offset(x: -4, y: -2)
                
                    
                Rectangle()
                    .fill(.white.opacity(0.7))
                    .frame(height: 1)
                    
                    
                    TitleView(“TIME“)
                    
                TextField(„“Race lenght (hh:mm)", text: $taskTime)
                    .ubuntu(16, .regular)
                    .tint(.white)
                    .foregroundColor(.white)
                    .padding()
                    .background(RoundedRectangle(cornerRadius: 80).fill(Color.black.opacity(0.1)))
                    .foregroundColor(.black)
                    .offset(x: -4, y: -2)
                
                Rectangle()
                    .fill(.white.opacity(0.7))
                    .frame(height: 1)
                }
                
                TitleView(“DATE“)
                    .padding(.top,15)
                
                HStack(alignment: .bottom, spacing: 12){
                    HStack(spacing: 12){
                        Text(taskDate.toString("EEEE dd MMMM"))
                            .ubuntu(16, .regular)
                        
                        /// - Custom Date  Picker
                        Image(systemName: "calendar")
                            .font(.title3)
                            .foregroundColor(.white)
                            .overlay{
                                DatePicker("", selection: $taskDate,displayedComponents: [.date])
                                    .blendMode(.destinationOver)
                            }
                    }
                
                    .offset(y: -5)
                    .overlay(alignment: .bottom){
                        Rectangle()
                            .fill(.white.opacity(0.7))
                            .frame(height: 1)
                            .offset(y: 5)
                    }
                    HStack(spacing: 12){
                        Text(taskDate.toString("hh:mm a"))
                            .ubuntu(16, .regular)
                        
                        /// - Custom Date  Picker
                        Image(systemName: "clock")
                            .font(.title3)
                            .foregroundColor(.white)
                            .overlay{
                                DatePicker("", selection: $taskDate,displayedComponents: [.hourAndMinute])
                                    .blendMode(.destinationOver)
                            }
                    }
                    .offset(y: -5)
                    .overlay(alignment: .bottom){
                        Rectangle()
                            .fill(.white.opacity(0.7))
                            .frame(height: 1)
                            .offset(y: 5)
                    }
                }
                .padding(.bottom,15)
            }
            .environment(\.colorScheme, .dark)
            .hAlign(.leading)
            .padding(15)
            .background {
                ZStack{
                    taskCategory.color
                    
                    GeometryReader{
                        let size = $0.size
                        Rectangle()
                            .fill(animateColor)
                            .mask {
                                Circle()
                            }
                            .frame(width: animate ? size.width * 2 : 0, height: animate ? size.height * 2 : 0)
                            .offset(animate ? CGSize(width: -size.width / 2, height: -size.height / 2) :size )
                    }
                    .clipped()
                }
                 .ignoresSafeArea()
            }
            
            VStack(alignment: .leading, spacing: 10){
                TitleView(“DESCRIPTION“, .gray)
                
                TextField(“About the activity:“, text: $taskDescription)
                    .ubuntu(16, .regular)
                    .padding(.top,2)
                
                Rectangle()
                    .fill(.black.opacity(0.2))
                    .frame(height: 1)
                
                TitleView(“Category“,.gray)
                    .padding(.top,15)
                
                LazyVGrid(columns: Array(repeating: .init(.flexible(),spacing: 20), count: 3), spacing: 15){
                    ForEach(Category.allCases,id: \.rawValue){category in
                        Text(category.rawValue.uppercased())
                            .ubuntu(12, .regular)
                            .hAlign(.center)
                            .padding(.vertical,5)
                            .background{
                                RoundedRectangle(cornerRadius: 5, style: .continuous)
                                    .fill(category.color.opacity(0.25))
                            }
                            .foregroundColor(category.color)
                            .contentShape(Rectangle())
                            .onTapGesture {
                                guard !animate else{return}
                                animateColor = category.color
                                withAnimation(.interactiveSpring(response: 0.7,dampingFraction: 1, blendDuration: 1)){
                                    animate = true
                                }
                                
                                DispatchQueue.main.asyncAfter(deadline: .now()   0.7){
                                    animate = false
                                    taskCategory = category
                                }
                            }
                    }
                }
                .padding(.top,5)
                
                Button {
                    /// - Creating Task And Pass it to the callback
                    let task = Task(dateAdded: taskDate, taskName: taskName, taskLenght: taskLenght, taskTime: taskTime, taskDescription: taskDescription, taskCategory: taskCategory)
                    onAdd(task)
                    dismiss()
                
                } label: {
                    
                    Text(“Create activity“)
                        .ubuntu(16, .regular)
                        .foregroundColor(.white)
                        .padding(.vertical,15)
                        .hAlign(.center)
                        .background{
                            Capsule()
                                .fill(animateColor.gradient)
                        }
                }
                .vAlign(.bottom)
                .disabled(taskName == "" || animate)
                .opacity(taskName == "" ? 0.6 : 1)
            }
            .padding(15)
        }
        .vAlign(.top)
    }
    

    @ViewBuilder
    func TitleView(_ value: String,_ color: Color = .white.opacity(0.7))->some View{
        Text(value)
            .ubuntu(12, .regular)
            .foregroundColor(color)
    }
}

struct AddTaskView_Previews: PreviewProvider {
    static var previews: some View {
        AddTaskView{task in }
            .environmentObject(DataStore())
    }
}

  • Related