0
//
//  CreateReminderView.swift
//  SwiftUICaneldarProject
//
//  Created by Chuljin Hwang on 2022/03/15.
//

import SwiftUI
struct CreateReminderView: View {
  @Environment(\.presentationMode) var presentationMode
    
  @EnvironmentObject var vm : CalendarViewModel
    
  @StateObject var remindervm = ReminderViewModel()
    
  @State private var textalert : String = ""
  @State private var taskTitle : String = ""
    @State private var isEditMode : Bool = false

  let selectedTask : TaskModel?
    
    init(task : TaskModel?) {
        self.selectedTask = task
        
        if let editTask = selectedTask {
            self.taskTitle = editTask.title
            print(taskTitle)
            print(editTask.title)
        }
    }
  
  var body: some View {
    VStack(spacing:20){
      Group{
        inputTextTitleSection
          .padding(.top,60)
        inputTextSection
        inputTextEditor
        
        Divider()
          .background(Color.caltheme.lightgray)
        
        inputDateSection
        
      }
      
      TextTitle(textTitle: "Select Color")
      circleColorSection
      Spacer()
      createButtonSection
        .padding(.bottom, 20)
    }
    .alert(isPresented: $remindervm.isshowAlert, content: remindervm.getAlert)
  }
  func isPressedCreateReminer() {
//    if remindervm.textCondition(){
        vm.addTask(title: taskTitle,content: remindervm.textEditorTodo, selectedColor: remindervm.selectedColor, reminderTime: Int(remindervm.minutes), taskDate: remindervm.taskDate)
      presentationMode.wrappedValue.dismiss()
//    }
  }
}

//struct CreateReminderView_Previews: PreviewProvider {
//  static var previews: some View {
//    CreateReminderView()
//      .preferredColorScheme(.dark)
//      .environmentObject(CalendarViewModel())
//  }
//}

extension CreateReminderView {
  private var inputTextTitleSection : some View{
    Text("Create a new remainder")
      .font(.title)
      .bold()
      .foregroundColor(Color.caltheme.secondaryText)
      .frame(maxWidth:.infinity, alignment: .leading)
      .padding(.horizontal)
  }
  
    
  @ViewBuilder
  private var inputTextSection : some View {
    HStack{
        TextField("Input your task...", text: $taskTitle)
          .foregroundColor(
            remindervm.createReminderText.isEmpty ?
            Color.caltheme.secondaryText : remindervm.selectedColor)
          .disableAutocorrection(true)
          .overlay(
            Image(systemName: "xmark.circle.fill")
              .padding()
              .offset(x: 10)
              .foregroundColor(remindervm.selectedColor)
              .opacity(remindervm.createReminderText.isEmpty ? 0.0 : 1.0)
              .onTapGesture {
                UIApplication.shared.closeKeyboard()
                remindervm.createReminderText = ""
              }
            ,alignment:  .trailing
          )
    }
    .font(.title3)
    .background(
      RoundedRectangle(cornerRadius: 15)
        .fill(Color.caltheme.background)
        .shadow(color: Color.caltheme.black.opacity(0.5), radius: 10, x: 0, y: 0)
    )
    .padding(.horizontal)
    Divider()
      .background(Color.caltheme.lightgray)
  }
    
  @ViewBuilder
  private var inputTextEditor: some View{
    VStack {
      TextEditor(text: $remindervm.textEditorTodo)
      
        .foregroundColor(remindervm.textEditorTodo.isEmpty ? Color.caltheme.secondaryText : remindervm.selectedColor)
        .frame(width: UIScreen.main.bounds.width * 0.9)
        .frame(height:200)
        .colorMultiply(Color.white.opacity(0.5))
        .padding(.leading)
        .padding(.trailing)
        .lineSpacing(8)
        .cornerRadius(15)
    }
    
  }
  
  @ViewBuilder
  private var inputDateSection: some View{
    DatePicker("Task Date", selection: $remindervm.taskDate)
    //    DatePicker("Task Date", selection: $remindervm.taskDate, displayedComponents: .date)
    //      .font(.title3)
    //      .padding(.horizontal)
    Divider()
      .background(Color.caltheme.lightgray)
  }
  
  private var circleColorSection: some View{
    HStack(spacing:5){
      ForEach(remindervm.circle, id:\.self){color in
        Circle()
          .frame(width: 40, height: 40)
          .foregroundColor(color)
          .background(
            Circle()
              .frame(width: 45, height: 45)
              .foregroundColor(color == remindervm.selectedColor ? Color.white : Color.clear)
              .shadow(color: color == remindervm.selectedColor ? Color.white : Color.clear, radius: 5, x: 0, y: 0))
          .onTapGesture {
            withAnimation(.easeIn){
              remindervm.selectedColor = color
            }
          }
      }
      .frame(maxWidth:.infinity)
      .padding(.horizontal)
    }
  }
  private var timeTextSection: some View{
    HStack(spacing : 0) {
      Text(remindervm.toProgress.roundCGFloat())
        .frame(width:50)
      Text("Minutes")
        .frame(width:130)
    }
    .font(.largeTitle.bold())
    .foregroundColor(Color.caltheme.secondaryText)
    .padding(.horizontal)
    .scaleEffect(1.5)
  }
  private var createButtonSection: some View{
    Button(action: {
      isPressedCreateReminer()
    }, label: {
      Text("Create Reminder")
    })
    .font(.title)
    .foregroundColor(Color.caltheme.secondaryText)
    .frame(maxWidth: .infinity)
    .frame(height:50)
    .background(remindervm.selectedColor)
    .cornerRadius(10)
    .padding(.horizontal)
  }
}

Hi! I'm wondering how I can pass model's title to @State var textTitle. enter image description here

As you can see from my picture, The model is passed well as optional type, and I did binding but the model's title is not passed to @State text. This is about Editing task's title.

The weird thing is

task works, but textTitle is "" by init(), I passed it to that but that is not works.

How I can handle this?

Kyungyun Lee
  • 115
  • 9
  • 1
    This needs a [Minimal Reproducible Example (MRE)](https://stackoverflow.com/help/minimal-reproducible-example). You haven't shown your view model. Are you sure that you aren't somehow passing nil in? – Yrb Apr 13 '22 at 22:53
  • @Yrb Thank you always! actually after this time, I succeeded to pass model by using State(initialValue:) method.!!! – Kyungyun Lee Apr 14 '22 at 08:45

1 Answers1

1

@State is declaring a source of truth, you don't pass data to it. If you did then it wouldn't be a source of truth it would have a dependency. To pass view data as a dependency to a sub-View either declare it as a let if you only need to read it or as @Binding var if you also need to change it. If the data changes and it is referenced in body then body will be called automatically. These features remove the need for legacy view model objects you would see in UIKit MVVM designs and this pattern should not be used in SwiftUI.

malhal
  • 26,330
  • 7
  • 115
  • 133