// // ContentView.swift // Swift-Basics // // Created by Guy Lapalme on 2023-07-16. // import SwiftUI @propertyWrapper struct Die { private var number:Int! // implicitly unwrapped optional to allow "limit" call in init() init(wrappedValue:Int){ number = limit(wrappedValue) } var wrappedValue: Int { get { number+1 } set { number = limit(newValue) } } var projectedValue:String { get {["one","two","three","four","five","six"][number]} } private func limit(_ val:Int) -> Int { return max(0,(val-1)%6) } } // custom View for an image over a text with a red border with padding struct ImageNameView:View { let image:String // mandatory parameter var name:String = "one" // optional parameter var body: some View { VStack { Image(systemName:image).imageScale(.large) Text(name).fontWeight(.bold) }.padding() .border(.red) } } struct DieView:View { @State private var number:Int = 0 @Binding var total:Int var body: some View { VStack { Image(systemName: number==0 ? "squareshape" : ("die.face."+String(number))) .imageScale(.large) Text(["—","one","two","three","four","five","six"][number]).fontWeight(.bold) }.padding() .border(.red) .onTapGesture { total = total - number number = Int.random(in:1...6) total = total + number } } } // use the custom View multiple times. struct ContentView: View { @State private var total:Int = 0 var body: some View { VStack { HStack{ DieView(total: $total) DieView(total: $total) } Text(total == 0 ? "Tap a die" : "Total: \(total)") }.padding().border(.blue) } } // use the ContentView for the Preview (useful for designing) struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }