I am calling for your help on my quest of making my first app. I am a teacher for the blind and visually impaired by day and am trying to make an app to use for our evaluations of students. In this particular section, we are evaluating their Positional/Spatial skills. We like the ease of using a toggle but I am having a hard time changing the bool value to an Int in order to get a score for each section. I would like true = 1 and false = 0. The numerical score will be listed below each section and I already have that coded out.
I have tried to use "Extension" to change the value but keep getting an error. I could change them all to a segmented picker and get close to the same ease of use but was hoping there was an easier fix since I've already coded about 100 of these. Thanks in advance!
struct caneSkills: View {
@State var front = false
@State var behind = false
@State var onTop = false
@State var below = false
@State var between = false
@State var nextTo = false
@State var under = false
@State var onBottom = false
@State var inBack = false
@State var onTheSide = false
var body: some View {
let psScore = (front behind onTop below between nextTo under onBottom inBack onTheSide)
NavigationView {
Form {
Section(header: Text("Positional/Spatial Concepts")) {
Toggle("Behind", isOn: $behind)
Toggle("Below", isOn: $below)
Toggle("In Back", isOn: $inBack)
Toggle("In Between", isOn: $between)
Toggle("In Front", isOn: $front)
Toggle("Next To", isOn: $nextTo)
Toggle("On The Bottom", isOn: $onBottom)
Toggle("On Side", isOn: $onTheSide)
Toggle("On Top", isOn: $onTop)
Group {
Toggle("Under", isOn: $under)
Text("Positional/Spatial Concepts Score: \(psScore) / 10")
.font(.headline)
.foregroundColor(Color.blue)
}
}
}
.navigationTitle("Cane Skills")
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
CodePudding user response:
Just for fun you can extend Bool type and add a value property to it. Then you can simply create a custom operator to sum all bool elements:
extension Bool {
var value: Int { self ? 1 : 0 }
public static func (lhs: Int, rhs: Bool) -> Int {
lhs rhs.value
}
}
I would also structure the data Skill
. This way you can have an array with all your skills:
struct Skill {
let name: String
var isOn: Bool
}
struct CaneSkills: View {
@State var skills = [
("Behind", false),
("Below", false),
("In Back", false),
("In Between", false),
("In Front", false),
("Next To", false),
("On The Bottom", false),
("On Side", false),
("On Top", false),
("Under", false)
].map(Skill.init)
var body: some View {
NavigationView {
Form {
Section(header: Text("Positional/Spatial Concepts")) {
ForEach(skills.indices, id: \.self) { index in
Toggle(skills[index].name, isOn: $skills[index].isOn)
}
Text("Score: \(psScore) / 10")
.font(.headline)
.monospacedDigit()
.foregroundColor(Color.blue)
.frame(maxWidth: .infinity, alignment: .trailing) }
}
.navigationTitle("Cane Skills")
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
extension CaneSkills {
var psScore: Int {
skills.reduce(0) { $0 $1.isOn }
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
CaneSkills()
}
}
CodePudding user response:
I don't think you need to convert a Bool
to an Int
to get the total score. You could get the score using this simple approach:
struct caneSkills: View {
@State var front = false
@State var behind = false
@State var onTop = false
@State var below = false
@State var between = false
@State var nextTo = false
@State var under = false
@State var onBottom = false
@State var inBack = false
@State var onTheSide = false
// -- here count all true values
var psScore: Int {
[front,behind,onTop,below,between,nextTo,under,onBottom,inBack,onTheSide].filter{ $0 }.count
}
var body: some View {
NavigationView {
Form {
Section(header: Text("Positional/Spatial Concepts")) {
Toggle("Behind", isOn:$behind)
Toggle("Below", isOn:$below)
Toggle("In Back", isOn:$inBack)
Toggle("In Between", isOn:$between)
Toggle("In Front", isOn:$front)
Toggle("Next To", isOn:$nextTo)
Toggle("On The Bottom", isOn:$onBottom)
Toggle("On Side", isOn:$onTheSide)
Toggle("On Top", isOn:$onTop)
Group{
Toggle("Under", isOn:$under)
Text("Positional/Spatial Concepts Score: \(psScore) / 10")
.font(.headline)
.foregroundColor(Color.blue)
}
}
}
.navigationTitle("Cane Skills")
}
.navigationViewStyle(StackNavigationViewStyle())
}
}