Reputation: 11
I'm working on an app that calls an api and displays the data on 6 different cards. In the card view the data displays correctly. Once I place that view into another using .overlay() the UI is perfect but the data on each card is the same. Without .overlay() the data is correct but the UI is wrong. I've tried changing my ViewModel variable in the views to @EnvironmentObject, @StateObject, & @ObservedObject with no luck. I can't figure out if this is a bug or I am missing something. Any help is greatly appreciated.
This view displays data correctly:
import SwiftUI
struct TopActivityCardView: View {
// @EnvironmentObject var vm: ViewModel
@StateObject var vm = ViewModel()
var timePeriod = ""
var body: some View {
ZStack {
ScrollView{
ForEach(vm.fetch(), id: \.title) { item in
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color.darkBlue)
.frame(height: 120, alignment: .center)
.padding(.top, 80)
.overlay(
ActivityTitleView(activityTitle: item.title)
).overlay(
ActivityHoursView(workHours: item.timeframes.weekly.current)
).overlay(
ActivityEllipisView()
).overlay(
TimePeriodView(timePeriod: "Last Week", weeklyHrs:
item.timeframes.weekly.previous)
)
}
}
}
}
}
struct TopActivityCardView_Previews: PreviewProvider {
static var previews: some View {
TopActivityCardView()
.environmentObject(ViewModel())
}
}
This view is where the problem occurs:
import SwiftUI
struct RectCardView: View {
var colorArray: [(colorName: Color, imageName: String)] = [(Color.work, "icon-work"),
(Color.play, "icon-play"), (Color.study, "icon-study"), (Color.exercise, "icon-
exercise"), (Color.social, "icon-social"), (Color.selfCare, "icon-self-care")]
// @StateObject var vm = ViewModel()
@ObservedObject var vm = ViewModel()
var body: some View {
ZStack{
ScrollView{
ForEach(colorArray, id: \.imageName) { colorName, imageName in
RoundedRectangle(cornerRadius: 20)
.foregroundColor(colorName)
.frame(height: 110, alignment: .center)
.overlay(
Image(imageName)
.brightness(-0.2)
.frame(width: 60, height: 20, alignment: .topLeading)
.offset(x: 103, y: -60)
).clipped()
/// If I take .overlay() off the cards display correct data but UI is
not correct.
/// With overlay UI is correct but data on cards is all the same.
.overlay{
TopActivityCardView()
.padding(.top, -40)
}
.padding(.top, 20)
}
}
}
}
}
struct RectCardView_Previews: PreviewProvider {
static var previews: some View {`enter code here`
RectCardView()
.environmentObject(ViewModel())
}
}
Upvotes: 1
Views: 486
Reputation: 769
In TopActivityCardView, you are making a new view model (@StateObject var vm = ViewModel()
).
It isn't using the same view model as RectCardView
, so the data is different.
You could pass the view into TopActivityCardView by using an environment object:
// code…
struct TopActivityCardView: View {
@EnvironmentObject var vm: ViewModel
// more code…
}
.overlay{
TopActivityCardView()
.environmentObject(vm)
.padding(.top, -40)
}
Upvotes: 1