Mobile App Dev 2021W: Tutorial 10: Difference between revisions
Line 8: | Line 8: | ||
# Change Converter-SB so it starts with a message saying to "Choose a conversion above" in the result area and the button says "Select conversion". | # Change Converter-SB so it starts with a message saying to "Choose a conversion above" in the result area and the button says "Select conversion". | ||
# Using the storyboard editor, add a Label at the bottom of the screen. This label should initially be blank. It should have a center horizontal alignment, span the width of the screen, and be anchored to the bottom of the safe area. | # Using the storyboard editor, add a Label at the bottom of the screen. This label should initially be blank. It should have a center horizontal alignment, span the width of the screen, and be anchored to the bottom of the safe area. | ||
# Modify ViewController.swift to make the label you added previously show a random encouragement message every time a conversion is selected. This label should go blank once the user starts typing in something. Add at least three messages, such as the following: | # Modify ViewController.swift to make the label you added previously show a random encouragement message every time a conversion is selected OR if the label area is touched. This label should go blank once the user starts typing in something. Add at least three messages, such as the following: | ||
#* You | #* You are choosing wisely! | ||
#* Keep going! Almost there! | #* Keep going! Almost there! | ||
#* | #* Welcome to Converter-SB! | ||
==Code== | ==Code== |
Revision as of 03:11, 7 April 2021
Tasks/Questions
- Download and run Converter-SB. How similar is its execution to Converter2 from Tutorial 2? How similar to Converter2A from Tutorial 6?
- How are connections made between Main.storyboard and ViewController.swift? How does this compare to the connections between activity_main.xml and MainActivity.kt from Tutorial 6?
- How is layout specified in Main.storyboard? How similar is this to how layout was specified in Converter2 and Converter2A?
- How does the flow of control of Converter-SB compare to Converter2 and Converter2A?
- Why do you think that Converter-SB doesn't have a proper menu?
- Change Converter-SB so it starts with a message saying to "Choose a conversion above" in the result area and the button says "Select conversion".
- Using the storyboard editor, add a Label at the bottom of the screen. This label should initially be blank. It should have a center horizontal alignment, span the width of the screen, and be anchored to the bottom of the safe area.
- Modify ViewController.swift to make the label you added previously show a random encouragement message every time a conversion is selected OR if the label area is touched. This label should go blank once the user starts typing in something. Add at least three messages, such as the following:
- You are choosing wisely!
- Keep going! Almost there!
- Welcome to Converter-SB!
Code
Conversions.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) {
let toS = String(format: "%.3f", to)
return "\(from) \(self.convFrom) is \(toS) \(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 =
["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)
]
let availConversions = [String] (conversions.keys)
ViewController.swift
//
// ViewController.swift
// Converter-SB
//
// Created by Anil Somayaji on 2021-04-06.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet var fromField: UITextField!
@IBOutlet weak var result: UILabel!
@IBOutlet weak var convButton: UIButton!
var convIndex = 0
var conv = conversions[availConversions[0]]!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func updateConversion() {
convIndex = (convIndex + 1 ) % availConversions.count
conv = conversions[availConversions[convIndex]]!
convButton.setTitle("Conversion: \(availConversions[convIndex])", for: .normal)
}
@IBAction func doConversion() {
if let fromS = fromField.text {
if let from = Double(fromS) {
result.text =
conv.formatConversion(from)
} else {
result.text = "Please enter a number."
}
}
}
}
Main.storyboard
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="Converter_SB" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="VJ7-bt-qir">
<rect key="frame" x="0.0" y="122" width="375" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<connections>
<action selector="doConversion" destination="BYZ-38-t0r" eventType="editingChanged" id="WEr-SS-N11"/>
</connections>
</textField>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QgR-df-1nY">
<rect key="frame" x="0.0" y="44" width="375" height="30"/>
<state key="normal" title="Button"/>
<connections>
<action selector="updateConversion" destination="BYZ-38-t0r" eventType="touchUpInside" id="u10-i8-VVe"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QHi-YO-lly">
<rect key="frame" x="0.0" y="164" width="375" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="VJ7-bt-qir" secondAttribute="trailing" id="1By-U1-T9I"/>
<constraint firstItem="QgR-df-1nY" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="3rM-HL-fub"/>
<constraint firstItem="QHi-YO-lly" firstAttribute="top" secondItem="VJ7-bt-qir" secondAttribute="bottom" constant="8" id="4Mw-3g-c0Y"/>
<constraint firstItem="VJ7-bt-qir" firstAttribute="top" secondItem="QgR-df-1nY" secondAttribute="bottom" constant="48" id="IBz-Q9-HJr"/>
<constraint firstAttribute="trailing" secondItem="QHi-YO-lly" secondAttribute="trailing" id="LsV-b9-Mq7"/>
<constraint firstItem="QHi-YO-lly" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="NS2-ki-p00"/>
<constraint firstItem="QHi-YO-lly" firstAttribute="top" secondItem="VJ7-bt-qir" secondAttribute="bottom" constant="8" symbolic="YES" id="NX0-K4-DfK"/>
<constraint firstAttribute="trailing" secondItem="QgR-df-1nY" secondAttribute="trailing" id="ckB-TL-gBc"/>
<constraint firstItem="QgR-df-1nY" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="44" id="q2m-Gg-fyA"/>
<constraint firstItem="VJ7-bt-qir" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="tT6-p8-3IJ"/>
</constraints>
</view>
<connections>
<outlet property="convButton" destination="QgR-df-1nY" id="6Dj-hw-rOA"/>
<outlet property="fromField" destination="VJ7-bt-qir" id="hkS-Oj-aWr"/>
<outlet property="result" destination="QHi-YO-lly" id="QEU-E4-Ty3"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-215" y="40"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>