Timer and onReceive in SwiftUI

Updated:

Timer and onReceive in SwiftUI

Timer into our view and then every time that timer goes off we’re going to do something on the screen. So we’re going to startoff very simply by just putting the current time on the screen and every second it’s going to update the time

A timer is actually a publisher it is an object that publishes values over time that’s what a publisher is and then we’re going to use the on receive call which is a really convenient swiftUI function so that we can listen to that publisher also known as subscribing

// Current time Example
import SwiftUI

struct TimerBootCamp: View {
// MARK: -  PROPERTY
let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect()

// Current Time
@State var currentDate: Date = Date()
var dateFormatter: DateFormatter {
let formatter = DateFormatter()
// formatter.dateStyle = .medium
formatter.timeStyle = .medium
return formatter
}

// MARK: -  BODY
var body: some View {
ZStack {
  // background
  RadialGradient(
    gradient: Gradient(colors: [Color.purple, Color.blue]),
    center: .center,
    startRadius: 5,
    endRadius: 500)
    .ignoresSafeArea()

  // Foreground
  Text(dateFormatter.string(from: currentDate))
    .font(.system(size: 100, weight: .semibold, design: .rounded))
    .foregroundColor(.white)
    .lineLimit(1)
    .minimumScaleFactor(0.1)
} //: ZSTACK
.onReceive(timer) { value in
  currentDate = value
}
}
}

스크린샷

// CountDown example

struct TimerBootCamp: View {
// MARK: -  PROPERTY
let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect()

// Countdown
@State var count: Int = 10
@State var finishedText: String? = nil

// MARK: -  BODY
var body: some View {
ZStack {
// background
RadialGradient(
  gradient: Gradient(colors: [Color.purple, Color.blue]),
  center: .center,
  startRadius: 5,
  endRadius: 500)
  .ignoresSafeArea()
// Foreground
  Text(finishedText ?? "\(count)")
    .font(.system(size: 100, weight: .semibold, design: .rounded))
    .foregroundColor(.white)
    .lineLimit(1)
    .minimumScaleFactor(0.1)
} //: ZSTACK
.onReceive(timer) { _ in
if count <= 1 {
  finishedText = "Wow!"
} else {
  count -= 1
}
}
}
}

스크린샷

// Countdown to date
struct TimerBootCamp: View {
// MARK: -  PROPERTY
let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect()

// Countdown to date
@State var timeRemaining: String = ""
let futureDate: Date = Calendar.current.date(byAdding: .hour, value: 1, to: Date()) ?? Date()

// MARK: -  BODY
var body: some View {
ZStack {
// background
RadialGradient(
  gradient: Gradient(colors: [Color.purple, Color.blue]),
  center: .center,
  startRadius: 5,
  endRadius: 500)
  .ignoresSafeArea()

// Foreground

  Text(timeRemaining)
    .font(.system(size: 100, weight: .semibold, design: .rounded))
    .foregroundColor(.white)
    .lineLimit(1)
    .minimumScaleFactor(0.1)
} //: ZSTACK
.onReceive(timer) { _ in
updateTimeRemaing()
}
}

// MARK: -  FUNCTION
func updateTimeRemaing() {
let remaining = Calendar.current.dateComponents([.minute, .second], from: Date(), to: futureDate)
let minute = remaining.minute ?? 0
let second = remaining.second ?? 0
timeRemaining = "\(minute) minutes \(second) seconds"
}
}

스크린샷

// Animation counter

struct TimerBootCamp: View {
// MARK: -  PROPERTY
let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()

// Animation counter
@State var count: Int = 0

// MARK: -  BODY
var body: some View {
ZStack {
// background
RadialGradient(
  gradient: Gradient(colors: [Color.purple, Color.blue]),
  center: .center,
  startRadius: 5,
  endRadius: 500)
  .ignoresSafeArea()

// Foreground
HStack {
  Circle()
    .offset(y: count == 1 ? -20 : 0)
  Circle()
    .offset(y: count == 2 ? -20 : 0)
  Circle()
    .offset(y: count == 3 ? -20 : 0)
} //: HSTACK
.frame(width: 150)
.foregroundColor(.white)
} //: ZSTACK
.onReceive(timer) { _ in
withAnimation(.easeInOut(duration: 0.5)) {
  count = count == 3 ? 0 : count + 1
}
}
}
}

스크린샷

// automatic Tabview
struct TimerBootCamp: View {
// MARK: -  PROPERTY
let timer = Timer.publish(every: 2.0, on: .main, in: .common).autoconnect()
// Animation counter
@State var count: Int = 1

// MARK: -  BODY
var body: some View {
ZStack {
// background
RadialGradient(
  gradient: Gradient(colors: [Color.purple, Color.blue]),
  center: .center,
  startRadius: 5,
  endRadius: 500)
  .ignoresSafeArea()

// Foreground
TabView(selection: $count) {
  Rectangle()
    .foregroundColor(.red)
    .tag(1)
  Rectangle()
    .foregroundColor(.blue)
    .tag(2)
  Rectangle()
    .foregroundColor(.green)
    .tag(3)
  Rectangle()
    .foregroundColor(.orange)
    .tag(4)
  Rectangle()
    .foregroundColor(.pink)
    .tag(5)
} //: TAB
.frame(height: 200)
.tabViewStyle(PageTabViewStyle())
} //: ZSTACK
.onReceive(timer) { _ in
withAnimation(.spring()) {
  count = count == 5 ? 1 : count + 1
}
}
}
}

스크린샷


🗃 Reference

SwiftUI Thinking - https://www.youtube.com/watch?v=ymXRX6ZB-J0&list=PLwvDm4VfkdpiagxAXCT33Rkwnc5IVhTar&index=26

Categories:

Updated:

Leave a comment