0

I have three Views exchanging information, ContentView, TimerView and TaskView. I used @Binding in TaskView to bring data from TaskView to ContentView, now I want to use that data to pass into TimerView.

I created a @State variable in ContentView to store the data from TaskView, but when I try to use that @State variable to pass data to TimerView it isn't giving me any desirable results.

Now if you see the TasksView call in ContentView, I get the output for the print statement, but in the main TimerView, it doesn't change from the default I set as @State variable in timerInfo.

Any help is appreciated, thank you.

Code for ContentView ->

//
//  ContentView.swift
//  ProDActivity
//
//  Created by Vivek Pattanaik on 5/27/21.
//

import SwiftUI

struct TimerInfo : Identifiable {
    let id = UUID()
    //    let taskIndex : Int
//    let taskProjectName : String
    var timerTaskName : String
    var timerMinutes : Float
    let timerIntervals : Int
    var timerPriority : String
    var timerShortbreakMinute : Float
    var timerLongbreakMinute : Float
    var timerLongbreakInterval : Int
   
}



struct ContentView: View {
    init() {
        UITabBar.appearance().backgroundColor = UIColor.init(Color("TabBar "))
    }
    
//    @State var selection: Tab = .dasboard
    @State var timerInfo = TimerInfo(timerTaskName: "Sample Task 1", timerMinutes: 30, timerIntervals: 10, timerPriority: "High Priority", timerShortbreakMinute: 5, timerLongbreakMinute: 15, timerLongbreakInterval: 3)
  
    var body: some View {
    
        
        TabView {
            TimerView(defaultTimeRemaining: self.timerInfo.timerMinutes * 60, timeRemaining: self.timerInfo.timerMinutes * 60)
                .tabItem {
                    Image(systemName: "clock.fill")
                    Text("Timer")
                }.tag(0)
            
            TasksView(didClickTimer: { info in
                self.timerInfo.timerTaskName = info.timerTaskName
                self.timerInfo.timerMinutes = info.timerMinutes
                self.timerInfo.timerPriority = info.timerPriority
                self.timerInfo.timerShortbreakMinute = info.timerShortbreakMinute
                self.timerInfo.timerLongbreakMinute = info.timerLongbreakMinute
                self.timerInfo.timerLongbreakInterval = info.timerLongbreakInterval
                
                print("\(self.timerInfo.timerMinutes)ContentView")
                
            })
                .tabItem {
                    Image(systemName: "doc.plaintext.fill")
                    Text("Tasks")
                }.tag(1)
               
            StatisticsView()
                .tabItem {
                    Image(systemName: "chart.pie.fill")
                    Text("Statistics")
                }.tag(3)
                
            SettingsView()
                .tabItem {
                    Image(systemName: "gearshape.fill")
                    Text("Settings")
                }.tag(4)
        
        }
        .font(.headline)
        .accentColor(Color("AccentColor"))
        .environment(\.colorScheme, .dark)

    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Code for TasksView ->

//
//  TasksView.swift
//  ProDActivity
//
//  Created by Vivek Pattanaik on 5/30/21.
//

import SwiftUI

struct TaskLabels : Identifiable {
    let id = UUID()
    //    let taskIndex : Int
    //    let taskProjectName : String
    let taskName : String
    let taskPriority : String
    let taskIntervals : String
    let taskMinutes : String
    let shortBreakMinutes : String
    let longBreakMinutes : String
    let longBreakIntervals : String
}

struct TaskRow: View {
    let tasks : TaskLabels
    
    var body: some View {
        HStack(alignment: .center, spacing: 10) {
            Image(tasks.taskPriority)
                .frame(width: 40, height: 40, alignment: .center)
            VStack(alignment: .leading, spacing:4){
                Text(tasks.taskName)
                    .font(.system(size: 15))
                Text("\(tasks.shortBreakMinutes) Min Breaks")
                    .font(.system(size: 13))
            }
            .frame(width: 100, height: 20, alignment: .leading)
            
            
            Spacer()
            VStack(alignment: .trailing, spacing:4){
                Text("0/\(tasks.taskIntervals)")
                Text("\(tasks.taskMinutes) Min Tasks")
                    .font(.system(size: 13))
            }
            .frame(width: 90, height: 20, alignment: .trailing)
            .padding()
            
        }
    }
}


struct TasksView: View {
    //    @Binding var timeSelected : Float
    @State var addTasksModalView: Bool = false
    @State var taskLabels : [TaskLabels] = []
    
    var didClickTimer : (TimerInfo) -> ()
    
    var body: some View {
        NavigationView{
            if taskLabels.count != 0 {
                List{
                    ForEach(taskLabels) { task in
                        HStack {
                            Button(action: {
                                self.didClickTimer(.init(timerTaskName: task.taskName, timerMinutes: Float(task.taskMinutes)!, timerIntervals: Int(task.taskIntervals)!, timerPriority: task.taskPriority, timerShortbreakMinute: Float(task.shortBreakMinutes)!, timerLongbreakMinute: Float(task.longBreakMinutes)!, timerLongbreakInterval: Int(task.longBreakIntervals)!))
                                print(task.taskMinutes)
                            }, label: {
                                TaskRow(tasks: task)
                            })
                            
                        }
                    }
                    .onDelete(perform: self.deleteRow)
                }
                .navigationBarTitle("Tasks")
                .navigationBarItems(trailing: Button(action: {
                    self.addTasksModalView = true
                }, label: {
                    Image(systemName: "plus.square.on.square")
                        .resizable()
                        .frame(width: 26, height: 26, alignment: .leading)
                        .foregroundColor(Color.accentColor)
                }))
                .sheet(isPresented: $addTasksModalView, content: {
                    AddTasks(addTaskPresented: $addTasksModalView) { tasks in
                        taskLabels.append(tasks)
                    }
                })
            } else {
                Text("")
                    .navigationTitle("Tasks")
                    .navigationBarTitle("Tasks")
                    .navigationBarItems(trailing: Button(action: {
                        self.addTasksModalView = true
                    }, label: {
                        Image(systemName: "plus.square.on.square")
                            .resizable()
                            .frame(width: 26, height: 26, alignment: .leading)
                            .foregroundColor(Color.accentColor)
                    }))
                    .sheet(isPresented: $addTasksModalView, content: {
                        AddTasks(addTaskPresented: $addTasksModalView) { tasks in
                            taskLabels.append(tasks)
                        }
                    })
            }
        }
        .environment(\.colorScheme, .dark)
        
    }
    private func deleteRow(at indexSet: IndexSet){
        self.taskLabels.remove(atOffsets: indexSet)
    }
}

//struct TasksView_Previews: PreviewProvider {
//    static var previews: some View {
//        TasksView()
//    }
//}

TimerView Code ->

//
//  TimerView.swift
//  ProDActivity
//
//  Created by Vivek Pattanaik on 5/27/21.
//

import SwiftUI


struct TimerView: View {
    let lineWidth : CGFloat = 11
    let radius : CGFloat = 150
    // to pass into the struct
//    @State var taskTime = 300
    @State  var defaultTimeRemaining : Float
    @State  var timeRemaining : Float 
    @State private var isActive = false
    @State private var showButtons = false
    @State private var stopAlert = false
    @State private var pausePressed = false
    @State private var stopPressed = false
   // @State private var timeRemainingSeconds : CGFloat = 25
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        
        
//        self.defaultTimeRemaining = timerInfo.timerMinutes
   
        VStack(spacing : 60) {
            ZStack{
                RoundedRectangle(cornerRadius: 7)
                    .frame(width: 300, height: 70)
                    .foregroundColor(Color("TabBar "))
            }
            ZStack(alignment: Alignment(horizontal: .center, vertical: .center)) {
                    Circle()
                        .stroke(Color.gray, style: StrokeStyle(lineWidth: lineWidth, lineCap: .round))
                        .opacity(0.2)
                    
                    Circle()
                        .trim(from: 1 - CGFloat(((defaultTimeRemaining-timeRemaining)/defaultTimeRemaining)), to: 1 )
                        .stroke(Color.accentColor, style: StrokeStyle(lineWidth: lineWidth, lineCap: .round))
                        .rotationEffect( .degrees(-90))
                        .animation(.easeInOut)
                    
                    // VStack for the timer and seesions
                    VStack {
//                        Text("\(Int(timeRemaining)):\(Int(timeRemainingSeconds))")
                        Text("\(timeString(time: Int(timeRemaining)))")
                            .font(.system(size: 50)).fontWeight(.medium)
                        Text("0 of 5 Sessions")
                            .font(.system(size: 20)).fontWeight(.medium)
                    }
            }.frame(width: radius*2, height: radius*2)
            
            
            // BEGIN, STOP, PAUSE BUTTONS
            HStack(spacing: 25){
                if showButtons == false {
                    Button(action: {
                    }, label: {
                        ZStack {
                            Rectangle()
                                .frame(width: 176, height: 55, alignment: .center)
                                .foregroundColor(Color.accentColor)
                                .cornerRadius(5)
                            Button(action: {
                                self.showButtons.toggle()
                                isActive.toggle()
                            }, label: {
                                Text("BEGIN")
                                    .foregroundColor(Color.white)
                                    .font(.system(size: 23).weight(.medium))
                                    .frame(width: 176, height: 55, alignment: .center)
                            })
                        }
                        
                    
                    })
                } else if showButtons == true {
                    HStack {
                        ZStack {
                            Rectangle()
                                .frame(width: 152, height: 55, alignment: .center)
                                .foregroundColor(Color("LightDark"))
                                .cornerRadius(5)
                                .border(Color.accentColor, width: 2)
                
                            Button(action: {
                                self.stopPressed.toggle()
                                self.pausePressed = true
                                if isActive == true {
                                    isActive.toggle()
                                    self.stopAlert = true
                                } else {
                                    self.stopAlert = true
                                }
                    
                            }, label: {
                                Text("STOP")
                                    .foregroundColor(Color.accentColor)
                                    .font(.system(size: 23).weight(.medium))
                                    .frame(width: 152, height: 55, alignment: .center)
                            })
                            .alert(isPresented: $stopAlert) {
                                Alert(title: Text("Are you sure you want to stop?"),
                                      message: Text("This will stop the timer and task associated with it."),
                                      primaryButton: .destructive(Text("Yes"), action: {
                                        self.showButtons = false
                                        timeRemaining = defaultTimeRemaining
                                }),
                                      secondaryButton: .cancel({
                                        isActive = false
                                        pausePressed = true
                                      })
                                )
                                
                            }
                             
                        }
                        
                        
                        ZStack {
                            Rectangle()
                                .frame(width: 152, height: 55, alignment: .center)
                                .foregroundColor(pausePressed ? Color.accentColor : Color("LightDark"))
                                .cornerRadius(5)
                                .border(pausePressed ? Color.accentColor : Color.accentColor, width: 2)
                                
                            Button(action: {
                                pausePressed.toggle()
                                if pausePressed == true {
                                    isActive = false
                                } else {
                                    isActive = true
                                }
                            }, label: {
                                Text("\(pausePressed ? "RESUME" : "PAUSE")")
                                    .foregroundColor(pausePressed ? Color("TabBar ") : Color.accentColor)
                                    .font(.system(size: 23).weight(.medium))
                                    
                                    .frame(width: 152, height: 55, alignment: .center)
                            })
                            
                        }
                    }
                    
                }
                }
        }.onReceive(timer, perform: { _ in
            guard isActive else {return}
            if timeRemaining > 0 {
                timeRemaining -= 1
            } else {
                isActive = false
                showButtons = false
                self.timer.upstream.connect().cancel()
            }
        })
        }
    
    func timeString(time: Int) -> String {
            let minutes = Int(time) / 60 % 60
            let seconds = Int(time) % 60
            return String(format:"%02i:%02i", minutes, seconds)
        }
    }

//struct TimerView_Previews: PreviewProvider {
//    static var previews: some View {
//        TimerView()
//    }
//}

//func buttonChange(){
//
//}
Vivek Pattanaik
  • 90
  • 1
  • 13
  • Can you include code for `TimerView`? Or better a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) – aheze May 31 '21 at 20:19
  • Hi, I added TimerView, I didn't add it initially, because I just got it working and it looks pretty messy, but it takes in two parameters and gives me a timer view. – Vivek Pattanaik May 31 '21 at 20:31
  • Instead of passing data back via closure, use `@Binding` – aheze May 31 '21 at 20:36
  • Im sorry, which file are we talking, the taskview to contentview or contentview to timerview – Vivek Pattanaik May 31 '21 at 20:49
  • TaskView to ContentView. Put `@Binding` inside `TaskView` that stores a `TaskLabels`. – aheze May 31 '21 at 20:55
  • Okay sorry if this is annoying but can you be specific. I tried making `@Binding` `TaskLabels`and passing it into `ContentView`, but I am confused how it is different from TimerInfo in the didClickTimer. – Vivek Pattanaik May 31 '21 at 21:58
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/233151/discussion-between-vivek-pattanaik-and-aheze). – Vivek Pattanaik May 31 '21 at 23:18

0 Answers0