Dmitry
Dmitry

Reputation: 15

Cannot convert value of type 'Binding<Date>' to expected argument type 'Date'

I'm trying pass date use Binding. This is where i'm getting this error next to Text

Cannot convert value of type 'Binding' to expected argument type 'Date'

if I remove style: .date i'm getting another error

Initializer 'init(_:)' requires that 'Binding' conform to 'StringProtocol'

struct ProfileView<ViewModel: ViewModelType>: View {
    @ObservedObject var viewModel: ViewModel    
    @State var selectedDate: Date = Date()
    
    init(with viewModel: ViewModel) {
        self.viewModel = viewModel
    }

    var body: some View {
        VStack(alignment: .leading) {
        Text( Binding<Date>(
                get: { viewModel.selectedDate },
                set: { _ in viewModel.setDate(selectedDate) }), style: .date )

        }
    }
}
final class ViewModel: ViewModelType {
    
    var selectedDate: Date = Date()
    
    func setDate(_ selectedDate: Date) {
        self.selectedDate = selectedDate
    }
}
 DatePicker("", selection: $selectedDate, displayedComponents: .date)

protocol ViewModelType: ObservableObject {
       
    var selectedDate: Date { get }
    func setDate(_ selectedDate: Date)
    
}

I wold like set the date use func setDate()

Upvotes: 0

Views: 2559

Answers (2)

malhal
malhal

Reputation: 30551

In SwiftUI we only pass in the data the View needs so it should be

struct ProfileView: View {
    
    let selectedDate: Date
    
    var body ...
}

Upvotes: 0

dudette
dudette

Reputation: 856

The error you get is because your Text(...) in ProfileView requires a Date, but you are giving it a Binding<Date>.

I suggest you try the following code to set the selectedDate in your ViewModel. The @Published var selectedDate: Date will get updated automatically in your views, whenever the viewModel is changed. There is no need for a separate func setDate(...).

struct ContentView: View {
    @StateObject var viewModel = ViewModel()
    
    var body: some View {
        VStack {
            ProfileView(viewModel: viewModel)
            DatePicker("", selection: $viewModel.selectedDate, displayedComponents: .date)
        }
    }
}

struct ProfileView: View {
    @ObservedObject var viewModel: ViewModel
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(viewModel.selectedDate, style: .date )
        }
    }
}

final class ViewModel: ObservableObject {
    @Published var selectedDate: Date = Date()
}

Upvotes: 0

Related Questions