Mobile App Dev 2022W: Tutorial 5: Difference between revisions
Line 17: | Line 17: | ||
==Tasks== | ==Tasks== | ||
==Code== | ==[https://homeostasis.scs.carleton.ca/~soma/mad-2022w/code/textanalyzer-3.zip textanalyzer-3 textanalyzer-3 Code]== | ||
===[https://homeostasis.scs.carleton.ca/~soma/mad-2022w/code/textanalyzer-3/ViewController.swift ViewController.swift]=== | |||
<syntaxhighlight lang="swift" line> | |||
// | |||
// ViewController.swift | |||
// textanalyzer-3 | |||
// | |||
// Created by Anil Somayaji on 2/3/22. | |||
// | |||
import UIKit | |||
class ViewController: UIViewController { | |||
@IBOutlet var t: UITextField! | |||
@IBOutlet weak var analysisMenuButton: UIButton! | |||
@IBOutlet weak var analysisResult: UILabel! | |||
@IBOutlet weak var appTitle: UILabel! | |||
var analysisMode = "None" | |||
// override func viewDidLoad() { | |||
// super.viewDidLoad() | |||
// } | |||
override func viewWillAppear(_ animated: Bool) { | |||
super.viewWillAppear(animated) | |||
setupAnalysisMenu() | |||
updateAnalysis() | |||
} | |||
func setupAnalysisMenu() { | |||
var menuItems: [UIAction] = [] | |||
for mode in analysis.keys { | |||
let item = UIAction(title: mode) { | |||
(action) in | |||
self.analysisMode = mode | |||
self.updateAnalysis() | |||
} | |||
menuItems.append(item) | |||
} | |||
let analysisMenu = UIMenu(title: "", children: menuItems) | |||
analysisMenuButton.showsMenuAsPrimaryAction = true | |||
analysisMenuButton.menu = analysisMenu | |||
} | |||
func updateAnalysis() { | |||
if let inputText = t.text { | |||
if let analysisFunc = analysis[analysisMode] { | |||
let r = analysisFunc(inputText) | |||
analysisResult.text = analysisMode + ": " + r | |||
} else { | |||
analysisResult.text = "Please choose an analysis mode." | |||
} | |||
} | |||
} | |||
@IBAction func doAnalysis(_ sender: Any) { | |||
updateAnalysis() | |||
} | |||
} | |||
func countUpper(s: String) -> String { | |||
var count = 0 | |||
let upperCase: Set<Character> = | |||
["A","B","C","D","E","F","G","H","I","J","K","L","M", | |||
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z"] | |||
for c in s { | |||
if (upperCase.contains(c)) { | |||
count += 1 | |||
} | |||
} | |||
return String(count) | |||
} | |||
let analysis: [String: (String) -> String] = [ | |||
"Count": countCharacters, | |||
"Upper Case": countUpper | |||
] | |||
func countCharacters(s: String) -> String { | |||
let charcount = s.count | |||
return String(charcount) | |||
} | |||
</syntaxhighlight> | |||
===[https://homeostasis.scs.carleton.ca/~soma/mad-2022w/code/textanalyzer-3/Main.storyboard Main.storyboard]=== | ===[https://homeostasis.scs.carleton.ca/~soma/mad-2022w/code/textanalyzer-3/Main.storyboard Main.storyboard]=== |
Revision as of 02:11, 9 February 2022
This tutorial is still being developed.
In this tutorial you will be playing with textanalyzer-3, which implements the same text analyzer functionality as Tutorial 2's textanalyzer-1 and [Mobile App Dev 2022W: Assignment 1|Assignment 1's textanalyzer-2]. This version, however, uses UIKit/Storyboard, not SwiftUI.
Getting Started
Unlike past tutorials, here we are textanalyzer-3 supplying the contents of the entire project rather than just one file. If you have problems with this project you'll need to re-create the project as follows:
- Create a new iOS (not multiplatform) App. The interface should be "Storyboard" (NOT SwiftUI) and the language should be Swift.
Key Concepts & APIs
Questions
Tasks
textanalyzer-3 textanalyzer-3 Code
ViewController.swift
//
// ViewController.swift
// textanalyzer-3
//
// Created by Anil Somayaji on 2/3/22.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet var t: UITextField!
@IBOutlet weak var analysisMenuButton: UIButton!
@IBOutlet weak var analysisResult: UILabel!
@IBOutlet weak var appTitle: UILabel!
var analysisMode = "None"
// override func viewDidLoad() {
// super.viewDidLoad()
// }
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupAnalysisMenu()
updateAnalysis()
}
func setupAnalysisMenu() {
var menuItems: [UIAction] = []
for mode in analysis.keys {
let item = UIAction(title: mode) {
(action) in
self.analysisMode = mode
self.updateAnalysis()
}
menuItems.append(item)
}
let analysisMenu = UIMenu(title: "", children: menuItems)
analysisMenuButton.showsMenuAsPrimaryAction = true
analysisMenuButton.menu = analysisMenu
}
func updateAnalysis() {
if let inputText = t.text {
if let analysisFunc = analysis[analysisMode] {
let r = analysisFunc(inputText)
analysisResult.text = analysisMode + ": " + r
} else {
analysisResult.text = "Please choose an analysis mode."
}
}
}
@IBAction func doAnalysis(_ sender: Any) {
updateAnalysis()
}
}
func countUpper(s: String) -> String {
var count = 0
let upperCase: Set<Character> =
["A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
for c in s {
if (upperCase.contains(c)) {
count += 1
}
}
return String(count)
}
let analysis: [String: (String) -> String] = [
"Count": countCharacters,
"Upper Case": countUpper
]
func countCharacters(s: String) -> String {
let charcount = s.count
return String(charcount)
}
Main.storyboard
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_7" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<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="textanalyzer_3" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="428" height="926"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Text Analyzer" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZtZ-ps-7Ye">
<rect key="frame" x="107.33333333333333" y="130" width="213.33333333333337" height="41"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="34"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Result Area" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1Vv-DZ-Mly">
<rect key="frame" x="170.66666666666666" y="498" width="86.999999999999972" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Enter Text" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="lai-Vo-ERj">
<rect key="frame" x="167.66666666666666" y="446" width="92.999999999999972" height="34"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits"/>
<connections>
<action selector="doAnalysis:" destination="BYZ-38-t0r" eventType="editingChanged" id="nO1-M0-6Er"/>
</connections>
</textField>
<button opaque="NO" contentMode="scaleToFill" ambiguous="YES" showsMenuAsPrimaryAction="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OZw-vK-PXJ">
<rect key="frame" x="164.66666666666666" y="46" width="98.999999999999972" height="30"/>
<state key="normal" title="Analysis Menu"/>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="OZw-vK-PXJ" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="5v2-LY-EP2"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="1Vv-DZ-Mly" secondAttribute="bottom" constant="10" id="Qa6-s1-ne8"/>
<constraint firstItem="ZtZ-ps-7Ye" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="UGF-av-neF"/>
<constraint firstItem="OZw-vK-PXJ" firstAttribute="top" relation="lessThanOrEqual" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="10" id="XYA-0a-ubh"/>
<constraint firstItem="ZtZ-ps-7Ye" firstAttribute="top" relation="greaterThanOrEqual" secondItem="OZw-vK-PXJ" secondAttribute="bottom" constant="10" id="cFf-s5-fgz"/>
<constraint firstItem="1Vv-DZ-Mly" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="psz-eR-tP5"/>
<constraint firstItem="lai-Vo-ERj" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="rod-O1-UBb"/>
<constraint firstItem="lai-Vo-ERj" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="z38-IR-hwi"/>
</constraints>
</view>
<connections>
<outlet property="analysisMenuButton" destination="OZw-vK-PXJ" id="1Ec-3D-09d"/>
<outlet property="analysisResult" destination="1Vv-DZ-Mly" id="rO4-z7-K7C"/>
<outlet property="appTitle" destination="ZtZ-ps-7Ye" id="xVP-yj-fvd"/>
<outlet property="t" destination="lai-Vo-ERj" id="AkQ-xR-U8T"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="29.600000000000001" y="83.208395802098963"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>