swiftxcodestructswiftuicgfloat

I can't get CGFloat at struct[CGFloat]


Hi I'm a collage student who made some graph that show how user sleep well. I get date from date picker, and I made function to change date to CGFloat. But I can't put CGFloat in struct. Here is my code. I'm gonna made more sleep data as number of date of month.

Xcode version is 11.2.1 and I made application by swiftui

import SwiftUI

struct graph_view: View {

@State var sleepdata : [[CGFloat]] = [
    [300,205,105,0,0,105,0,205,105,105,205,105,300],
    [300,105,105,0,0,105,0,105,205,205,105,105,205],
    [205,105,105,0,105,0,0,0,105,0,205,205,300]
]

func getDate()->String{
 let datetextFormatter = DateFormatter()
    datetextFormatter.locale = Locale(identifier: "ko_KR")
    datetextFormatter.dateFormat = "YYYY년 MM월 dd일"
 let stringdate = datetextFormatter.string(from: date)
 return stringdate
}
func getDate2()->CGFloat{
    let datetextFormatter2 = DateFormatter()
    datetextFormatter2.locale = Locale(identifier:"ko_KR")
    datetextFormatter2.dateFormat = "dd"
    let stringdate2 = datetextFormatter2.string(from: date)
    let myFloat = (stringdate2 as NSString).floatValue
    return CGFloat(myFloat)
}

@State var date = Date()


var body: some View {
    ZStack{
        Form {
            Section (header: Text("\(getDate()) 그래프")){
                VStack {
                DatePicker(selection: $date, displayedComponents: .date, label: { Text("날짜 선택") })

                }

            }

        }
        VStack{
                VStack{
                HStack(){
                    VStack(alignment: .trailing){ Text("waken").font(.system(size: 10)).offset(y:-125)

                        Text("light sleep").font(.system(size: 10)).offset(y:-45)

                        Text("deep sleep").font(.system(size: 10)).offset(y:45)

                        Text("REM").font(.system(size: 10)).offset(y:125)

                    }
                    Group{
                        Bargraph(value: sleepdata[(getDate2())][0])
                        Spacer()
                        Bargraph(value: sleepdata[0][1])
                        Spacer()
                        Bargraph(value: sleepdata[0][2])
                        Spacer()
                        Bargraph(value: sleepdata[0][3])
                        Spacer()
                        Bargraph(value: sleepdata[0][4])
                        Spacer()
                        }
                }
                }.padding(.horizontal,10)
                .animation(.default)
                HStack(){
                    Text("수면").font(.system(size: 10)).offset(x:35)
                    Spacer()
                    Text("기상").font(.system(size: 10))
                }.padding(.horizontal,5)
                }
            }
        }
    }




struct Bargraph: View{

var value : CGFloat
var body: some View{
    VStack{
        ZStack(alignment: .bottom){
        Capsule().frame(width : 10, height: 300).foregroundColor(Color(#colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)))
        Capsule().frame(width : 10, height: value).foregroundColor(Color(#colorLiteral(red: 0.501960814, green: 0.501960814, blue: 0.501960814, alpha: 1)))
        }
    }
}
}

struct graph_view_Previews: PreviewProvider {
static var previews: some View {
    graph_view()
}
}

At here I got error massage

Bargraph(value: sleepdata[(getDate2())][0])
                        Spacer()

Cannot subscript a value of type '[[CGFloat]]' with an argument of type 'CGFloat'

I just wonder that why I can't use CGFloat at struct even form is right. And I want to know how to fix it or how to make it works. Thanks for read beginners question. I'd really appreciate it if you could come up with a solution.


Solution

  • You have to pass in an Int as your subscript, because that is the required syntax.

    Something like this..

    sleepdata[0][Int(getDate2())]
    

    But I think the real problem is your sleepdata data structure. I think you should just declare it as an array of CGFloats if that's what you want, not an array of arrays of CGFloats. Although admittedly, I do not know what the data signifies, nor how you are using it.

    As it is though, the subscript taken from Int(getDate2()) will cause an "Index out of range" error for any value returned that is above 12.

    Edit

    I didn't notice you put 0 as the inner subscript, so the corrected form would be:

    sleepdata[Int(getDate2())][0]
    

    As your data only has 3 sub-arrays, any subscript above 2 will yield a similar error.

    So in the context of the bar graph call, it should work with:

    Bargraph( value: sleepdata [Int(getDate2())] [0] )
    

    Added whitespace to make it clear how we are accessing the 2D array.