Using ObservableObject to animate in SwiftUI

It’s pretty easy to accomplish this animation using the ObservableObject. Let me show you how. Use the below class to display all your views one by one.

struct RFWeekdayListView: View {
	@ObservedObject var settings = UserSettings()
	var weekdays : [String] = [""]
	var parentController : SwipeController?
	init(weekdays:[String]) {
		self.weekdays = weekdays
	}
    var body: some View {
		GeometryReader { reader in
			ScrollView {
				VStack {
					ForEach(0 ..< self.weekdays.count) { pos in
						DaySwiftUIView(pos: pos, size: reader.size, delay: Float(pos), color: colors[pos])
					}
				}
			}
		}
    }
}

Display your views DaySwiftUIView using a for loop. Let’s write the actual class which does this animation. The single line of code which animates the view is

.animation(Animation .spring(response: 0.3, dampingFraction: 0.5, blendDuration: 0.5) //.easeInOut(duration: 0.5) .delay(Double(self.delay)))

Inside your swift class which is shown below, use the offset property to set the frame depending on the @Published property as shown here.
.offset(x: self.settings.removeDayView ? 0 : size.width, y: 0)

//
//  DaySwiftUIView.swift
//  swipeRight
//
//  Copyright © 2019 darshan. All rights reserved.
//

import SwiftUI

struct DaySwiftUIView: View {
	@ObservedObject var settings = UserSettings()
	private var pos : Int = 0
	private var size : CGSize = .zero
	private var delay : Float = 0
	private var color : Color = .clear
	init(pos : Int, size : CGSize, delay : Float, color: Color) {
		self.pos = pos
		self.size = size
		self.delay = delay * 0.1
		self.color = color
	}
    var body: some View {
		Text(weekdays[self.pos])
			.background(Rectangle()
				.fill(self.color)
				.frame(width: size.width, height: size.height/7))
			.animation(Animation
					.spring(response: 0.3, dampingFraction: 0.5, blendDuration: 0.5)
					//.easeInOut(duration: 0.5)
				.delay(Double(self.delay)))
			.onAppear {
				self.settings.removeDayView = true
			}
			.onTapGesture {
				self.settings.removeDayView = false
				let scores = ["position": self.pos]
				NotificationCenter.default.post(name: NSNotification.Name("dismissSwiftUI"), object: nil, userInfo: scores)
			}
			.offset(x: self.settings.removeDayView ? 0 : size.width, y: 0)
			.frame(width: size.width, height: size.height/7, alignment: .center)
    }
}

struct DaySwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
		DaySwiftUIView(pos: 0, size: .zero, delay: 1, color: .black)
    }
}

UserSettings is the name of the ObservableObject class which has a published variable. The removeDayView variable is the one which emits the changes to the view.

import Foundation
class UserSettings : ObservableObject {
	@Published var removeDayView : Bool = false
}

Leave a Reply

Your email address will not be published. Required fields are marked *