swift 如何获取用户默认值以保存数组[已关闭]

kmpatx3s  于 2023-06-28  发布在  Swift
关注(0)|答案(1)|浏览(98)

已关闭,此问题需要更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
        
    }
}
}
9ceoxa92

9ceoxa921#

我敢打赌,当你保存在用户默认值中时,你会得到一个错误消息,一个Int数组不是你可以保存在用户默认值中的东西。

相关问题