Difference between revisions of "Mobile App Dev 2022W: Tutorial 5"

From Soma-notes
Jump to navigation Jump to search
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.zip textanalyzer-3 project]


===[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 22:11, 8 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:

  1. 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>