已关闭,此问题需要更focused。目前不接受答复。
**想改善这个问题吗?**更新问题,使其仅通过editing this post关注一个问题。
昨天关门了。
Improve this question
我试图使用用户默认值来保存一个名为“globalY”的值,并让一个线图读取它。由于某种原因,我似乎无法得到线图加载保存的值。不知道我在这件事上错在哪里。我所做的是在更新视图中,我使用用户默认值保存了它,但是当我打开折线图时,由于某种原因它没有加载。
struct ChartsView: View {
let daysOfWeek = ["Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"]
@State private var globalYLineData: [Int] = []
@State private var sumText: Int = 0
@State private var sessionTimeCount: Int = 0
@State private var mostCommonImage: Image = Image(systemName: "questionmark") // Default image if array is empty
@State private var mostCommonText: String = ""
var body: some View {
ScrollView {
ZStack {
Rectangle()
.foregroundColor(Color.cyan)
.edgesIgnoringSafeArea(.top)
VStack(spacing: 10) {
// First row
VStack {
Text(getFormattedDate())
.font(.title)
.padding()
.background(Color.white)
.cornerRadius(15)
.padding(10)
}
.frame(maxWidth: .infinity)
// Second row
HStack {
VStack {
Text("Total Mins")
.font(.title3)
.multilineTextAlignment(.center)
Text("\(sumText)") // Display the sum of sessionTime array
.font(.title)
.padding(.top, 10)
}
.padding()
Divider()
.background(Color.gray)
.padding(.top, 25)
.padding(.bottom, 25)
VStack {
Text("Total Sessions")
.font(.title3)
.multilineTextAlignment(.center)
Text("\(sessionTimeCount)") // Display the count of sessionTime array
.font(.title)
.padding(.top, 5)
}
.padding()
Divider()
.background(Color.gray)
.padding(.top, 25)
.padding(.bottom, 25)
VStack {
Text("Most time spent at")
.padding(.bottom, 10)
.multilineTextAlignment(.center)
mostCommonImage // Display the most common image
.resizable()
.frame(width: 100, height: 100)
.cornerRadius(15)
Text("the " + mostCommonText)
.padding(.bottom, 10)
}
.cornerRadius(15)
.padding()
}
.background(Color.white)
.cornerRadius(15)
// Third row (Graph)
VStack(spacing: 0) {
Text("This Week")
.font(.title2)
.padding(.bottom, 10)
GeometryReader { geometry in
VStack(spacing: 0) {
LineGraph(randomData: $globalYLineData)
.frame(maxHeight: min(geometry.size.height, 200))
}
.frame(maxWidth: .infinity)
.frame(minHeight: 50)
.onAppear {
}
}
}
.padding(10)
.frame(minHeight: 260)
.background(Color.white)
.cornerRadius(15)
// Calendar view
CustomCalendarView()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.white)
.cornerRadius(15)
}
.padding(10)
}
.onAppear {
updateSessionTimeValues()
}
}
}
func getFormattedDate() -> String {
let formatter = DateFormatter()
formatter.dateFormat = "dd - MMMM - yyyy"
return formatter.string(from: Date())
}
func updateSessionTimeValues() {
//step 3
globalYLineData = globalSortedData.map { $0.1 }
// Step 1: Retrieve the saved globalY value from UserDefaults
if let savedGlobalY = UserDefaults.standard.array(forKey: "globalY") as? [Int] {
// Step 2: Check if globalYLineData is empty, and if so, set its value to the saved globalY
if globalYLineData.isEmpty {
globalYLineData = savedGlobalY
}
}
let imageSelect = UserDefaults.standard.array(forKey: "sessionLocation") as? [String] ?? []
//getting most common image in array
if let mostCommon = imageSelect.mostCommonElement() {
mostCommonImage = Image(mostCommon) // Use the most common image
}
//getting most common text in array
if let mostText = imageSelect.mostCommonElement() {
mostCommonText = mostText
}
let sessionTime = UserDefaults.standard.array(forKey: "sessionTime") as? [Int] ?? []
sumText = sessionTime.reduce(0, +)
sessionTimeCount = sessionTime.count
var values = minValueArray
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let calendar = Calendar.current
let currentDate = Date()
// Initialize the dictionary with all days of the week and initial value of 0
var result: [String: Int] = [:]
calendar.weekdaySymbols.forEach { weekday in
result[weekday] = 0
}
//datesOfSessionsArray
for i in 0..<datesOfSessionsArray.count {
if let date = dateFormatter.date(from: datesOfSessionsArray[i]) {
// Check if the date is within the last 7 days
if calendar.dateComponents([.day], from: date, to: currentDate).day! <= 7 {
let weekday = calendar.component(.weekday, from: date)
let weekdaySymbol = calendar.weekdaySymbols[weekday - 1]
// Accumulate the values for each day
result[weekdaySymbol]! += values[i]
}
}
}
//WHEN UPDATE IS CALLED I.E NEW SCREN.
// Create an array of tuples representing key-value pairs in the desired order
let orderedWeekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
let orderedResult = orderedWeekdays.map { (weekday) -> (String, Int) in
return (weekday, result[weekday]!)
}
print(orderedResult)
globalSortedData = orderedResult
globalXLineData = globalSortedData.map { $0.0 }
globalYLineData = globalSortedData.map { $0.1 }
print("yyyyyyyyyyy")
print(globalYLineData)
//i want to save globalYLineData data here
UserDefaults.standard.set(globalYLineData, forKey: "globalY")
print(UserDefaults.standard.array(forKey: "globalY"))
print("This is it")
}
}
struct LineGraph: View {
@Binding var randomData: [Int]
let daysOfWeek = ["M", "T", "W", "T", "F", "S", "S"]
@State private var selectedDataPoint: Int? = nil
var body: some View {
GeometryReader { geometry in
VStack {
ZStack {
LinearGradient(gradient: Gradient(colors: [Color.blue.opacity(0.3), Color.cyan.opacity(0.3), Color.white.opacity(0.1)]), startPoint: .top, endPoint: .bottom)
.clipShape(
Path { path in
let width = geometry.size.width
let height = geometry.size.height - 50
let stepWidth = width / CGFloat(daysOfWeek.count - 1)
let stepHeight = height / CGFloat((randomData.max() ?? 1) - (randomData.min() ?? 0))
for (index, dataPoint) in randomData.enumerated() {
let x = stepWidth * CGFloat(index)
let y = height - (CGFloat(dataPoint - (randomData.min() ?? 0)) * stepHeight) + 20
if index == 0 {
path.move(to: CGPoint(x: x, y: y))
} else {
let previousDataPoint = randomData[index - 1]
let previousY = height - (CGFloat(previousDataPoint - (randomData.min() ?? 0)) * stepHeight) + 20
let controlPoint1 = CGPoint(x: x - stepWidth/2, y: previousY)
let controlPoint2 = CGPoint(x: x - stepWidth/2, y: y)
path.addCurve(to: CGPoint(x: x, y: y), control1: controlPoint1, control2: controlPoint2)
}
}
path.addLine(to: CGPoint(x: width + width, y: height + 50))
path.addLine(to: CGPoint(x: -width, y: height + 50))
path.closeSubpath()
}
)
.opacity(0.8)
Path { path in
let width = geometry.size.width
let height = geometry.size.height - 50
let stepWidth = width / CGFloat(daysOfWeek.count - 1)
let stepHeight = height / CGFloat((randomData.max() ?? 1) - (randomData.min() ?? 0))
for (index, dataPoint) in randomData.enumerated() {
let x = stepWidth * CGFloat(index)
let y = height - (CGFloat(dataPoint - (randomData.min() ?? 0)) * stepHeight) + 20
if index == 0 {
path.move(to: CGPoint(x: x, y: y))
} else {
let previousDataPoint = randomData[index - 1]
let previousY = height - (CGFloat(previousDataPoint - (randomData.min() ?? 0)) * stepHeight) + 20
let controlPoint1 = CGPoint(x: x - stepWidth/2, y: previousY)
let controlPoint2 = CGPoint(x: x - stepWidth/2, y: y)
path.addCurve(to: CGPoint(x: x, y: y), control1: controlPoint1, control2: controlPoint2)
}
}
}
.stroke(Color.blue, lineWidth: 2)
let stepWidth = geometry.size.width / CGFloat(daysOfWeek.count - 1)
let height = geometry.size.height - 50
let stepHeight = height / CGFloat((randomData.max() ?? 1) - (randomData.min() ?? 0))
ForEach(0..<randomData.count, id: \.self) { index in
let x = CGFloat(index) * stepWidth
let y = height - (CGFloat(randomData[index] - (randomData.min() ?? 0)) * stepHeight) + 20
let day = daysOfWeek[index % daysOfWeek.count]
Text(day)
.font(.caption)
.foregroundColor(.gray)
.position(x: x, y: height + 40) // Adjust the y position here
}
Text("Y-axis")
.font(.caption)
.foregroundColor(.gray)
.rotationEffect(.degrees(-90))
.position(x: -16, y: geometry.size.height / 2)
ForEach(0..<randomData.count, id: \.self) { index in
let x = CGFloat(index) * stepWidth
let y = height - (CGFloat(randomData[index] - (randomData.min() ?? 0)) * stepHeight) + 20
let isSelected = selectedDataPoint == randomData[index]
ZStack {
Circle()
.fill(Color.blue.opacity(0.4))
.frame(width: 16, height: 16)
.position(x: x, y: y)
Circle()
.fill(Color.blue)
.frame(width: 8, height: 8)
.position(x: x, y: y)
}
.gesture(
TapGesture()
.onEnded { _ in
selectedDataPoint = randomData[index]
}
)
}
}
.frame(maxWidth: .infinity, maxHeight: 200)
.padding(.top, 10)
.padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) // Adjust padding values
if let selectedDataPoint = selectedDataPoint {
Text("\(Int(selectedDataPoint))" + " Mins")
.font(.caption)
.foregroundColor(.black)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
.onAppear(){
print("line appeared and globaly called")
print(UserDefaults.standard.array(forKey: "globalY"))
//when the line graph appears calling the global y values
}
}
}
1条答案
按热度按时间9ceoxa921#
我敢打赌,当你保存在用户默认值中时,你会得到一个错误消息,一个Int数组不是你可以保存在用户默认值中的东西。