Mobile App Dev 2021W: Tutorial 2
This tutorial is still being developed.
Introduction
Concepts
- Functions, closures
- command line synchronous interface
- iOS async interface
- dictionaries
- nested Views
Tasks
Code
Converter.swift
// Conversions.swift
struct Converter {
var convFrom = "From Type"
var convTo = "To Type"
var convert: (_ from: Double) -> Double?
func formatConversion(_ from: Double) -> String {
if let to = self.convert(from) {
return "\(from) \(self.convFrom) is \(to) \(self.convTo)."
} else {
return "Converting \(from) \(convFrom) to \(self.convTo) failed."
}
}
init(_ from: String, _ to: String, _ f: @escaping (_ from: Double) -> Double?) {
self.convFrom = from
self.convTo = to
self.convert = f
}
}
func InToCM(_ inch: Double) -> Double {
let cm = 2.54 * inch
return cm
}
let conversions: [String: Converter] =
["F to C": Converter("Farenheit", "Celsius",
{F in return ((F - 32.0)*(5/9))}),
"C to F": Converter("Celsius", "Farenheit",
{C in return ((9/5)*C + 32.0)}),
"km to mi": Converter("kilometers", "miles",
{k in
let m = k * 0.6213712
return m
}),
"inch to cm": Converter("inches", "centimeters",
InToCM)
]
ContentView.swift (Converter2)
// ContentView.swift (Converter2)
import SwiftUI
struct ContentView: View {
@State var convMode: String? = nil
@State var fromS = ""
var body: some View {
VStack{
ConvMenu(convMode: $convMode,
fromString: $fromS)
Spacer()
ConvOutput(convMode: $convMode,
fromString: $fromS)
Spacer()
Spacer()
}
}
}
struct ConvMenu: View {
@Binding var convMode: String?
@Binding var fromString: String
var body: some View {
let availConversions = [String](conversions.keys)
Menu("Conversions menu") {
ForEach(availConversions, id: \.self) {
conversion in
Button(conversion, action: {
convMode = conversion
fromString = ""
})
}
}
}
}
struct ConvOutput: View {
@Binding var convMode: String?
@Binding var fromString: String
var body: some View {
if let mode = convMode {
let conv = conversions[mode]!
TextField("Enter \(conv.convFrom)", text: $fromString)
Spacer()
if let from = Double(fromString) {
Text(conv.formatConversion(from))
}
} else {
Text("Please select a conversion")
Text("type from the menu above.")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
main.swift (Convert2Cmd)
// main.swift (Convert2Cmd)
var convAvail = conversions.keys.sorted()
func getChoice() -> String? {
print("Available Conversions:")
for i in 0..<convAvail.count {
print(" \(i+1). \(convAvail[i])")
}
print("Enter choice: ", terminator: "")
if let choice = readLine() {
if let c = Int(choice) {
if ((c > 0) && (c <= convAvail.count)) {
return convAvail[c-1]
}
}
}
return nil
}
let getConversion = {(_ choice: String) in
let conv = conversions[choice]!
print("\nEnter \(conv.convFrom): ", terminator: "")
if let vs = readLine() {
if let v = Double(vs) {
let res = conv.formatConversion(v)
print(res)
return
} else {
print("You didn't enter a number!")
}
}
}
if let choice = getChoice() {
getConversion(choice)
} else {
print("You didn't make a valid choice!")
}