UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: SwiftUI Text view refresh

Forums > SwiftUI

I wrote my first app. Yay :)

ok, I'm having trouble though having the view, which is just text, refresh without quiting and re-opening the app.

Anyone able to help point me in the right direction?

I'm running through a bunch of if/else depending on time of day/day of the week and returning 'Period' which is a String.

let Period = weekend(date: now)

struct ContentView: View {
    var body: some View {
        VStack{
            //Text("The current time is:")
            //Text(now, style: .time)
            //    .padding()
            Text(Period)
                .multilineTextAlignment(.center)
                //.padding()
        }
    }
}

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

2      

If Period is a String declaring it with let makes it immutable for the lifetime of the view. Try

@State var period = weekend(date: now) instead.

You have to declare your variable in the view itself because @State is only available in a View.

I just use lower case because upper case is usually the name of a class.

Depending on when and how the view should update you could use

struct ContentView: View {

    let period: String

    var body: some View {
        VStack{
            Text(period)
                .multilineTextAlignment(.center)
        }
    }
}

and call it with:

ContentView(period: weekend(now))

too.

2      

Thanks. Where would I put ContentView(period: weekend(now))?

I want the view to reload everytime I open the app. Right now I have to force quit and then reopen.

The plan right now is that the app is more glancable (probably make it a widget once I get the basics working).

2      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

That depends on when and where your weekend() method is called. With the provided code I can't tell you where to put it.

2      

It's called right before the struct ContentView: View{}

and is a 105 line function with a couple of nested if/else statements.

If you want I can paste the file, but it's a doozy of poorly written self taught code. :)

Edit: I was thinking... could/should the func weekend be created inside the struct? or is it best to leave it outside?

2      

You say you want to refresh ContentView but what triggers the refresh? A button?

2      

currently I guess nothing. but maybe a timer, or time of day? or pull to refresh.

hmm...

Is there a clean way to do it when the app comes back from the background? is that what the onAppear() is for?

2      

No, I don't think this will work with onAppear. onAppear is only called once when the view actually appears. The name is in my opinion misleading as it's more like viewDidLoad on UIKit was.

But you can call your function with this method.

https://www.hackingwithswift.com/books/ios-swiftui/how-to-be-notified-when-your-swiftui-app-moves-to-the-background

But you have to change the let period: String to @State var period: String because you want to modify a value in an already existing view.

And you have to make your function callable from ContentView, either a static function or weekend should be a function in ContentView.

2      

Figured this might be easier if I just post the whole file. Here it is in all it's beginning wonder. :)

//
//  ContentView.swift
//  CurrentPeriod
//
//  Created by Jonathon Lillie on 8/17/21.
//

import SwiftUI
import Foundation

let now = Date()

let calendar = Calendar.current
//let tz = TimeZone.abbreviation("UTC")
//var schedule1 = (period1Start: "08:30",
//                 period1End: "09:18",
//                 period2Start: "09:26",
//                 period2End: "10:14")

//Monday Period start and end times
let p1Start = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:08, minute: 30, second: 00)//"08:30"
let p1MonEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:09, minute: 18, second: 00)//"09:18"
let p2MonStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:09, minute: 26, second: 00)//"09:26"
let p2MonEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:10, minute: 14, second: 00)//"10:14"
let p3MonStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:10, minute: 22, second: 00)//"10:22"
let p3MonEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:11, minute: 15, second: 00)//"11:15"
let p4MonStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:11, minute: 23, second: 00)//"11:23"
let p4MonEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:12, minute: 11, second: 00)//"12:11"
let p5MonStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:12, minute: 49, second: 00)//"12:49"
let p5MonEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:13, minute: 37, second: 00)//"13:37"
let p6MonStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:13, minute: 45, second: 00)//"13:45"
let p6MonEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:14, minute: 33, second: 00)//"14:33"
let MonLunchStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:12, minute: 11, second: 00)//"12:11"
let MonLunchEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:12, minute: 41, second: 00)//"12:41"

//Tuesday - Friday Period start and end times
let p1tfEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:09, minute: 25, second: 00)//"09:25"
let p2tfStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:09, minute: 33, second: 00)//"09:33"
let p2tfEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:10, minute: 33, second: 00)//"10:33"
let p3tfStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:10, minute: 41, second: 00)//"10:41"
let p3tfEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:11, minute: 36, second: 00)//"11:36"
let p4tfStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:11, minute: 44, second: 00)//"11:44"
let p4tfEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:12, minute: 39, second: 00)//"12:39"
let p5tfStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:13, minute: 17, second: 00)//"13:17"
let p5tfEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:14, minute: 12, second: 00)//"14:12"
let p6tfStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:14, minute: 20, second: 00)//"14:20"
let p6tfEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:15, minute: 15, second: 00)//"15:15"
let tfLunchStart = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:12, minute: 39, second: 00)//"12:39"
let tfLunchEnd = DateComponents(calendar: calendar, timeZone: TimeZone(abbreviation: "PDT"), hour:13, minute: 09, second: 00)//"13:09"

//let currentTime = formatter.string(from: now) //formats Date() as String

let formatter = DateFormatter()
let formatter2 = DateFormatter()

let currentTime = dateComponents.hour! * 60 + dateComponents.minute!
let formatter4 = DateFormatter()
var Time = Date()
var currentPeriod = "Something went wrong"
var isWeekend = calendar.isDateInWeekend(now)

let dateComponents = calendar.dateComponents([.hour, .minute, .second], from: now)

func weekend(date:Date) -> String{
    if (isWeekend == false) {
        //formatter.dateStyle = .short
        //formatter.timeStyle = .short
        formatter.setLocalizedDateFormatFromTemplate("EEEE")
        formatter2.timeStyle = .short
        formatter4.setLocalizedDateFormatFromTemplate("HH:mm")

        currentPeriod = "It is not the weekend)"

        //var timeLeft = 0
        var timer: Timer?
        var timeLeftPeriodMonday = 48
        var timeLeftPeriod = 55
        var timeLeftPassing = 8
        var timeLeftLunch = 30
        if formatter.string(from: now) == "Monday"{ //it's Monday?
            let p1S = p1Start.hour! * 60 + p1Start.minute!
            let p1E = p1MonEnd.hour! * 60 + p1MonEnd.minute!
            let p2S = p2MonStart.hour! * 60 + p2MonStart.minute!
            let p2E = p2MonEnd.hour! * 60 + p2MonEnd.minute!
            let p3S = p3MonStart.hour! * 60 + p3MonStart.minute!
            let p3E = p3MonEnd.hour! * 60 + p3MonEnd.minute!
            let p4S = p4MonStart.hour! * 60 + p4MonStart.minute!
            let p4E = p4MonEnd.hour! * 60 + p4MonEnd.minute!
            let p5S = p5MonStart.hour! * 60 + p5MonStart.minute!
            let p5E = p5MonEnd.hour! * 60 + p5MonEnd.minute!
            let p6S = p6MonStart.hour! * 60 + p6MonStart.minute!
            let p6E = p6MonEnd.hour! * 60 + p6MonEnd.minute!
            let LunchS = MonLunchStart.hour! * 60 + MonLunchStart.minute!
            let LunchE = MonLunchEnd.hour! * 60 + MonLunchEnd.minute!

            if (currentTime > p1S && currentTime <= p1E){
                currentPeriod = "It's currently 1st Period\n1st Period ends at \(p1MonEnd.hour!):\(p1MonEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { timer in
                    if timeLeftPeriodMonday != 0 {
                        timeLeftPeriodMonday -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime > p2S && currentTime <= p2E){
                currentPeriod = "It's currently 2nd Period\n2nd Period ends at \(p2MonEnd.hour!):\(p2MonEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { timer in
                    if timeLeftPeriodMonday != 0 {
                        timeLeftPeriodMonday -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime > p3S && currentTime <= p3E){
                currentPeriod = "It's currently 3rd Period\n3rd Period ends at \(p3MonEnd.hour!):\(p3MonEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { timer in
                    if timeLeftPeriodMonday != 0 {
                        timeLeftPeriodMonday -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime > p4S && currentTime <= p4E){
                currentPeriod = "It's currently 4th Period\n4th Period ends at \(p4MonEnd.hour!):\(p4MonEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { timer in
                    if timeLeftPeriodMonday != 0 {
                        timeLeftPeriodMonday -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime > p5S && currentTime <= p5E){
                currentPeriod = "It's currently 5th Period\n5th Period ends at \(p5MonEnd.hour!):\(p5MonEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { timer in
                    if timeLeftPeriodMonday != 0 {
                        timeLeftPeriodMonday -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime >= p6S && currentTime <= p6E){
                currentPeriod = "It's currently 6th Period\n6th Period ends at \(p6MonEnd.hour!):\(p6MonEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { timer in
                    if timeLeftPeriodMonday != 0 {
                        timeLeftPeriodMonday -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime >= LunchS && currentTime <= LunchE){
                currentPeriod = "It's currently lunch\nLunch ends at \(MonLunchEnd.hour!):\(MonLunchEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { timer in
                    if timeLeftLunch != 0 {
                        timeLeftLunch -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime >= p1S && currentTime <= p6E){
                currentPeriod = "It's currently a passing period"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { timer in
                    if timeLeftPassing != 0 {
                        timeLeftPassing -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else{
                currentPeriod = "School is not in session!"
            }
        }
        else { //it's Tuesday - Friday
            currentPeriod = "It's not the weekend"
            let p1S = p1Start.hour! * 60 + p1Start.minute!
            let p1E = p1tfEnd.hour! * 60 + p1tfEnd.minute!
            let p2S = p2tfStart.hour! * 60 + p2tfStart.minute!
            let p2E = p2tfEnd.hour! * 60 + p2tfEnd.minute!
            let p3S = p3tfStart.hour! * 60 + p3tfStart.minute!
            let p3E = p3tfEnd.hour! * 60 + p3tfEnd.minute!
            let p4S = p4tfStart.hour! * 60 + p4tfStart.minute!
            let p4E = p4tfEnd.hour! * 60 + p4tfEnd.minute!
            let p5S = p5tfStart.hour! * 60 + p5tfStart.minute!
            let p5E = p5tfEnd.hour! * 60 + p5tfEnd.minute!
            let p6S = p6tfStart.hour! * 60 + p6tfStart.minute!
            let p6E = p6tfEnd.hour! * 60 + p6tfEnd.minute!
            let LunchS = tfLunchStart.hour! * 60 + tfLunchStart.minute!
            let LunchE = tfLunchEnd.hour! * 60 + tfLunchEnd.minute!
            if (currentTime > p1S && currentTime <= p1E){
                currentPeriod = "It's currently 1st Period\n1st Period ends at \(p1tfEnd.hour!):\(p1tfEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { timer in
                    if timeLeftPeriod != 0 {
                        timeLeftPeriod -= 1
                        //timeLeft = timeLeftPeriod

                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime > p2S && currentTime <= p2E){
                currentPeriod = "It's currently 2nd Period\n2nd Period ends at \(p2tfEnd.hour!):\(p2tfEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { timer in
                    if timeLeftPeriod != 0 {
                        timeLeftPeriod -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime > p3S && currentTime <= p3E){
                currentPeriod = "It's currently 3rd Period\n3rd Period ends at \(p3tfEnd.hour!):\(p3tfEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { timer in
                    if timeLeftPeriod != 0 {
                        timeLeftPeriod -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime > p4S && currentTime <= p4E){
                currentPeriod = "It's currently 4th Period\n4th Period ends at \(p4tfEnd.hour!):\(p4tfEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { timer in
                    if timeLeftPeriod != 0 {
                        timeLeftPeriod -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime > p5S && currentTime <= p5E){
                currentPeriod = "It's currently 5th Period\n5th Period ends at \(p5tfEnd.hour!):\(p5tfEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { timer in
                    if timeLeftPeriod != 0 {
                        timeLeftPeriod -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime >= p6S && currentTime <= p6E){
                currentPeriod = "It's currently 6th Period\n6th Period ends at \(p6tfEnd.hour!):\(p6tfEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { timer in
                    if timeLeftPeriod != 0 {
                        timeLeftPeriod -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime >= LunchS && currentTime <= LunchE){
                currentPeriod = "It's currently lunch\nLunch ends at \(tfLunchEnd.hour!):0\(tfLunchEnd.minute!)"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { timer in
                    if timeLeftLunch != 0 {
                        timeLeftLunch -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else if (currentTime >= p1S && currentTime <= p6E){
                currentPeriod = "It's currently a passing period"
                Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { timer in
                    if timeLeftPassing != 0 {
                        timeLeftPassing -= 1
                    } else {
                        timer.invalidate()
                    }
                }
            }
            else{
                currentPeriod = "School is not in session!"
            }
        }
        return currentPeriod
    }
    else {
        currentPeriod = "It's the weekend"
        return currentPeriod
    }
}

struct ContentView: View {
    @State private var period = weekend(date: now)
    @State var currentDate = Date()

    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        VStack{
            // displays the current time as "9:48 AM"
            Text("The current time is:")
            Text(currentDate, style: .time)
                .onReceive(timer) { input in currentDate = input}
                .padding()
            Text(period)
                .multilineTextAlignment(.center)
                .padding()
        }
    }
}

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

As you can see I figured out using a timer to update the time, but can't quite get it to work for "Text(period)"

2      

Call it in the onReceive as well:

struct ContentView: View {
    @State private var period = weekend(date: now)
    @State var currentDate = Date()

    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        VStack{
            // displays the current time as "9:48 AM"
            Text("The current time is:")
            Text(currentDate, style: .time)
                .onReceive(timer) { input in
                    currentDate = input
                    period = weekend(date: input)
                }
                .padding()
            Text(period)
                .multilineTextAlignment(.center)
                .padding()
        }
    }
}

2      

OH my, it was really that simple. :( Thank you very much for your help.

2      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.