This commit is contained in:
Micah Gomez 2021-07-05 16:18:00 -06:00
parent 62888718eb
commit eba43838c5
2 changed files with 597 additions and 8 deletions

View file

@ -1,24 +1,226 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
<!--View Controller--> <!--View Controller-->
<scene sceneID="tne-QT-ifu"> <scene sceneID="tne-QT-ifu">
<objects> <objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController"> <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="BPOrganizer" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="JjE-3R-0dR">
<rect key="frame" x="20" y="268" width="374" height="556"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="pocket" textLabel="pPO-Au-kTu" style="IBUITableViewCellStyleDefault" id="NuD-d3-EPB">
<rect key="frame" x="0.0" y="24.5" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="NuD-d3-EPB" id="A5E-54-QDa">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="pPO-Au-kTu">
<rect key="frame" x="20" y="0.0" width="334" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="0.0"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
</tableView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="M6l-dh-v8o">
<rect key="frame" x="20" y="832" width="82" height="30"/>
<state key="normal" title="New Bag"/>
<connections>
<action selector="AddBag:" destination="BYZ-38-t0r" eventType="touchUpInside" id="VXZ-Wf-zb1"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QJC-tE-0Q7">
<rect key="frame" x="110" y="832" width="82" height="30"/>
<state key="normal" title="Delete Bag"/>
<connections>
<action selector="DeleteBag:" destination="BYZ-38-t0r" eventType="touchUpInside" id="w8x-ZQ-EdE"/>
</connections>
</button>
<pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="AMo-Vi-91l">
<rect key="frame" x="20" y="44" width="374" height="216"/>
</pickerView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0P5-Xu-ynk">
<rect key="frame" x="312" y="832" width="82" height="30"/>
<state key="normal" title="New Pocket"/>
<connections>
<action selector="AddPocket:" destination="BYZ-38-t0r" eventType="touchUpInside" id="OH7-Er-AW7"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OQn-V0-43E">
<rect key="frame" x="222" y="832" width="82" height="30"/>
<state key="normal" title="Search"/>
<connections>
<action selector="SearchBags:" destination="BYZ-38-t0r" eventType="touchUpInside" id="gaw-B4-ONp"/>
</connections>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/> <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="QJC-tE-0Q7" firstAttribute="height" secondItem="M6l-dh-v8o" secondAttribute="height" id="0Zl-dn-4fg"/>
<constraint firstItem="M6l-dh-v8o" firstAttribute="top" secondItem="JjE-3R-0dR" secondAttribute="bottom" constant="8" symbolic="YES" id="74l-a7-mPa"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="AMo-Vi-91l" secondAttribute="trailing" constant="20" id="EoX-98-9JV"/>
<constraint firstItem="JjE-3R-0dR" firstAttribute="leading" secondItem="AMo-Vi-91l" secondAttribute="leading" id="F5p-xq-kSR"/>
<constraint firstItem="QJC-tE-0Q7" firstAttribute="leading" secondItem="M6l-dh-v8o" secondAttribute="trailing" constant="8" symbolic="YES" id="M7e-db-Z4h"/>
<constraint firstItem="JjE-3R-0dR" firstAttribute="top" secondItem="AMo-Vi-91l" secondAttribute="bottom" constant="8" symbolic="YES" id="QLK-Xb-9vC"/>
<constraint firstItem="0P5-Xu-ynk" firstAttribute="leading" secondItem="OQn-V0-43E" secondAttribute="trailing" constant="8" symbolic="YES" id="Sq4-va-8Wk"/>
<constraint firstItem="0P5-Xu-ynk" firstAttribute="height" secondItem="M6l-dh-v8o" secondAttribute="height" id="X6V-lM-1GZ"/>
<constraint firstItem="M6l-dh-v8o" firstAttribute="leading" secondItem="AMo-Vi-91l" secondAttribute="leading" id="Yyr-4o-PkO"/>
<constraint firstItem="AMo-Vi-91l" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="20" id="a3i-Vm-lXZ"/>
<constraint firstItem="AMo-Vi-91l" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="asx-pq-33o"/>
<constraint firstItem="QJC-tE-0Q7" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="cUe-et-0w3"/>
<constraint firstItem="QJC-tE-0Q7" firstAttribute="width" secondItem="M6l-dh-v8o" secondAttribute="width" id="cxo-91-hhn"/>
<constraint firstItem="OQn-V0-43E" firstAttribute="height" secondItem="M6l-dh-v8o" secondAttribute="height" id="eCn-RL-Rmd"/>
<constraint firstItem="0P5-Xu-ynk" firstAttribute="height" secondItem="M6l-dh-v8o" secondAttribute="height" id="eTI-qm-F9s"/>
<constraint firstItem="OQn-V0-43E" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="hM2-FL-AGE"/>
<constraint firstItem="0P5-Xu-ynk" firstAttribute="width" secondItem="M6l-dh-v8o" secondAttribute="width" id="imH-FQ-WEJ"/>
<constraint firstItem="OQn-V0-43E" firstAttribute="width" secondItem="M6l-dh-v8o" secondAttribute="width" id="lYl-0O-kVQ"/>
<constraint firstItem="OQn-V0-43E" firstAttribute="leading" secondItem="QJC-tE-0Q7" secondAttribute="trailing" constant="30" id="mMI-e1-oqC"/>
<constraint firstItem="0P5-Xu-ynk" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="oDf-ue-Cpb"/>
<constraint firstItem="M6l-dh-v8o" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="oPu-fG-UsB"/>
<constraint firstItem="JjE-3R-0dR" firstAttribute="trailing" secondItem="AMo-Vi-91l" secondAttribute="trailing" id="w94-ew-HvL"/>
<constraint firstItem="0P5-Xu-ynk" firstAttribute="trailing" secondItem="JjE-3R-0dR" secondAttribute="trailing" id="xcT-WD-wC7"/>
</constraints>
</view> </view>
<connections>
<outlet property="bagPicker" destination="AMo-Vi-91l" id="U0D-7U-eCv"/>
<outlet property="pocketsTable" destination="JjE-3R-0dR" id="K5w-mY-y1R"/>
<segue destination="3NQ-zC-3iZ" kind="presentation" id="404-5V-95l"/>
</connections>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="43" y="58"/>
</scene>
<!--VC2-->
<scene sceneID="viR-SX-wRd">
<objects>
<viewController storyboardIdentifier="ViewController2" title="VC2" id="3NQ-zC-3iZ" customClass="ViewController2" customModule="BPOrganizer" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="kNQ-x4-PpB">
<rect key="frame" x="0.0" y="0.0" width="414" height="842"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="kWs-6u-uk8">
<rect key="frame" x="20" y="121" width="374" height="649"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="pocketitem" textLabel="8ig-wi-DGr" style="IBUITableViewCellStyleDefault" id="S51-Ss-kkR">
<rect key="frame" x="0.0" y="24.5" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="S51-Ss-kkR" id="hbf-tV-wUU">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8ig-wi-DGr">
<rect key="frame" x="20" y="0.0" width="334" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="0.0"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
</tableView>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Tap to enter item name" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="3ma-jo-zcf">
<rect key="frame" x="20" y="78.5" width="290" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="words"/>
<connections>
<action selector="AddItem:" destination="3NQ-zC-3iZ" eventType="primaryActionTriggered" id="QA7-68-jFx"/>
</connections>
</textField>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="41C-O5-1Fi">
<rect key="frame" x="318" y="79" width="34" height="33"/>
<constraints>
<constraint firstAttribute="width" secondItem="41C-O5-1Fi" secondAttribute="height" multiplier="1:1" id="IAb-ak-noR"/>
</constraints>
<state key="normal" backgroundImage="plus.circle" catalog="system"/>
<connections>
<action selector="AddItem:" destination="3NQ-zC-3iZ" eventType="touchUpInside" id="3bY-HB-MhL"/>
</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="BTS-NM-Kjm">
<rect key="frame" x="20" y="20" width="374" height="38.5"/>
<fontDescription key="fontDescription" type="system" pointSize="32"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Cjd-RS-O0Z">
<rect key="frame" x="20" y="778" width="374" height="30"/>
<state key="normal" title="Dismiss"/>
<connections>
<action selector="DismissModal:" destination="3NQ-zC-3iZ" eventType="touchUpInside" id="sba-RD-TFW"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IRg-Eu-D1H">
<rect key="frame" x="360" y="80.5" width="34" height="34"/>
<state key="normal" backgroundImage="keyboard.chevron.compact.down" catalog="system"/>
<connections>
<action selector="DismissKB:" destination="3NQ-zC-3iZ" eventType="touchUpInside" id="3s5-Yw-922"/>
</connections>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="WDZ-rS-vIS"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="WDZ-rS-vIS" firstAttribute="trailing" secondItem="BTS-NM-Kjm" secondAttribute="trailing" constant="20" id="2fW-xV-m2B"/>
<constraint firstItem="IRg-Eu-D1H" firstAttribute="leading" secondItem="41C-O5-1Fi" secondAttribute="trailing" constant="8" symbolic="YES" id="82Z-TJ-zbb"/>
<constraint firstItem="BTS-NM-Kjm" firstAttribute="top" secondItem="WDZ-rS-vIS" secondAttribute="top" constant="20" id="8Ht-Q9-8Wh"/>
<constraint firstItem="Cjd-RS-O0Z" firstAttribute="top" secondItem="kWs-6u-uk8" secondAttribute="bottom" constant="8" symbolic="YES" id="D5B-yt-lcW"/>
<constraint firstItem="IRg-Eu-D1H" firstAttribute="width" secondItem="41C-O5-1Fi" secondAttribute="width" id="D5s-AI-7vX"/>
<constraint firstItem="41C-O5-1Fi" firstAttribute="height" secondItem="3ma-jo-zcf" secondAttribute="height" id="Ff4-JO-JIT"/>
<constraint firstItem="IRg-Eu-D1H" firstAttribute="bottom" secondItem="41C-O5-1Fi" secondAttribute="bottom" id="Go8-1z-n2S"/>
<constraint firstItem="3ma-jo-zcf" firstAttribute="leading" secondItem="WDZ-rS-vIS" secondAttribute="leading" constant="20" id="K5w-Mh-2Ws"/>
<constraint firstItem="IRg-Eu-D1H" firstAttribute="top" secondItem="41C-O5-1Fi" secondAttribute="top" id="OHG-Ii-Hh1"/>
<constraint firstItem="BTS-NM-Kjm" firstAttribute="leading" secondItem="WDZ-rS-vIS" secondAttribute="leading" constant="20" id="QEu-4c-AoI"/>
<constraint firstItem="kWs-6u-uk8" firstAttribute="leading" secondItem="WDZ-rS-vIS" secondAttribute="leading" constant="20" id="U2t-Rm-E6Y"/>
<constraint firstItem="Cjd-RS-O0Z" firstAttribute="leading" secondItem="kWs-6u-uk8" secondAttribute="leading" id="ZTI-1i-jYK"/>
<constraint firstItem="3ma-jo-zcf" firstAttribute="top" secondItem="BTS-NM-Kjm" secondAttribute="bottom" constant="20" id="Zxd-wS-hi1"/>
<constraint firstItem="Cjd-RS-O0Z" firstAttribute="trailing" secondItem="kWs-6u-uk8" secondAttribute="trailing" id="c9L-B1-CGO"/>
<constraint firstItem="WDZ-rS-vIS" firstAttribute="trailing" secondItem="kWs-6u-uk8" secondAttribute="trailing" constant="20" id="eOu-F7-988"/>
<constraint firstItem="kWs-6u-uk8" firstAttribute="top" secondItem="3ma-jo-zcf" secondAttribute="bottom" constant="8.5" id="k6v-gh-7kx"/>
<constraint firstItem="41C-O5-1Fi" firstAttribute="top" secondItem="BTS-NM-Kjm" secondAttribute="bottom" constant="20" id="m6f-Mo-EjY"/>
<constraint firstItem="Cjd-RS-O0Z" firstAttribute="bottom" secondItem="WDZ-rS-vIS" secondAttribute="bottom" id="myM-BA-hJR"/>
<constraint firstItem="IRg-Eu-D1H" firstAttribute="trailing" secondItem="kWs-6u-uk8" secondAttribute="trailing" id="q9P-6U-bqw"/>
<constraint firstItem="41C-O5-1Fi" firstAttribute="leading" secondItem="3ma-jo-zcf" secondAttribute="trailing" constant="8" symbolic="YES" id="tJ8-PC-UMP"/>
<constraint firstItem="41C-O5-1Fi" firstAttribute="leading" secondItem="3ma-jo-zcf" secondAttribute="trailing" constant="8" symbolic="YES" id="yIA-Ko-CgP"/>
</constraints>
</view>
<connections>
<outlet property="ItemName" destination="3ma-jo-zcf" id="pV2-bm-kMl"/>
<outlet property="PocketLabel" destination="BTS-NM-Kjm" id="QtU-Ux-cxg"/>
<outlet property="itemsTable" destination="kWs-6u-uk8" id="Hq2-XA-B3f"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="pzS-L6-Yiq" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="978.26086956521749" y="57.589285714285708"/>
</scene> </scene>
</scenes> </scenes>
<resources>
<image name="keyboard.chevron.compact.down" catalog="system" width="128" height="102"/>
<image name="plus.circle" catalog="system" width="128" height="121"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document> </document>

View file

@ -7,13 +7,400 @@
import UIKit import UIKit
class ViewController: UIViewController { protocol ObjectSavable {
func setObject<Object>(_ object: Object, forKey: String) throws where Object: Encodable
func getObject<Object>(forKey: String, castTo type: Object.Type) throws -> Object where Object: Decodable
}
enum ObjectSavableError: String, LocalizedError {
case unableToEncode = "Unable to encode object into data"
case noValue = "No data object found for the given key"
case unableToDecode = "Unable to decode object into given type"
var errorDescription: String? {
rawValue
}
}
extension UserDefaults: ObjectSavable {
func setObject<Object>(_ object: Object, forKey: String) throws where Object: Encodable {
let encoder = JSONEncoder()
do {
let data = try encoder.encode(object)
set(data, forKey: forKey)
} catch {
throw ObjectSavableError.unableToEncode
}
}
func getObject<Object>(forKey: String, castTo type: Object.Type) throws -> Object where Object: Decodable {
guard let data = data(forKey: forKey) else { throw ObjectSavableError.noValue }
let decoder = JSONDecoder()
do {
let object = try decoder.decode(type, from: data)
return object
} catch {
throw ObjectSavableError.unableToDecode
}
}
}
extension String {
func contains(find: String) -> Bool{
return self.range(of: find) != nil
}
func containsIgnoringCase(find: String) -> Bool{
return self.range(of: find, options: .caseInsensitive) != nil
}
}
struct passingValues{
static var bag:Int = 0
static var pocket:Int = 0
}
class pocket: Codable {
var pocketName: String = ""
var contents:[String] = []
}
class bag: Codable {
var bagName:String = ""
var pockets:[pocket] = []
}
class ViewController: UIViewController, UIDocumentPickerDelegate, UIPickerViewDataSource, UITableViewDataSource, UITableViewDelegate, UIPickerViewDelegate {
var bags:[bag] = []
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return bags.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return bags[row].bagName
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if (bags.count > 0){
print(bags[bagPicker.selectedRow(inComponent: 0)].pockets)
pocketsTable.reloadData()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (bags.count > 0){
return bags[bagPicker.selectedRow(inComponent: 0)].pockets.count
} else {
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "pocket", for: indexPath)
cell.textLabel?.text = bags[bagPicker.selectedRow(inComponent: 0)].pockets[indexPath.row].pocketName
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
bags[bagPicker.selectedRow(inComponent: 0)].pockets.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
do {
try UserDefaults.standard.setObject(bags, forKey: "bagsSavedData")
} catch {
print(error.localizedDescription)
}
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(bags[bagPicker.selectedRow(inComponent: 0)].pockets[indexPath.row].pocketName)
passingValues.bag = bagPicker.selectedRow(inComponent: 0)
passingValues.pocket = indexPath.row
print(passingValues.bag)
print(passingValues.pocket)
let NotificationVC = self.storyboard?.instantiateViewController(withIdentifier: "ViewController2") as! UIViewController
NotificationVC.modalPresentationStyle = .fullScreen
pocketsTable.reloadData()
self.present(NotificationVC, animated: true, completion: nil)
}
@IBOutlet var pocketsTable: UITableView!
@IBOutlet var bagPicker: UIPickerView!
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Do any additional setup after loading the view. // Do any additional setup after loading the view.
pocketsTable.dataSource = self
pocketsTable.delegate = self
bagPicker.dataSource = self
bagPicker.delegate = self
if (bags.count > 0){
bagPicker.selectRow(0, inComponent: 0, animated: true)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(true)
do {
bags = try UserDefaults.standard.getObject(forKey: "bagsSavedData", castTo: [bag].self)
print(bags)
} catch {
print(error.localizedDescription)
}
pocketsTable.reloadData()
bagPicker.reloadComponent(0)
}
override func viewDidDisappear(_ animated: Bool) {
do {
try UserDefaults.standard.setObject(bags, forKey: "bagsSavedData")
} catch {
print(error.localizedDescription)
}
}
@IBAction func AddBag(_ sender: Any) {
var newBagName:String = ""
let alert = UIAlertController(title: "Enter Bag Name", message: "", preferredStyle: .alert)
alert.addTextField { (textField) in
textField.text = ""
textField.autocapitalizationType = .words
textField.placeholder = "Bag Name"
}
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
let textField = alert?.textFields![0] // Force unwrapping because we know it exists.
print("Text field: \(textField!.text ?? "Bag")")
if ((textField!.text ?? "Bag") == ""){
return
}
newBagName = (textField!.text ?? "Bag")
let newBag:bag = bag.init()
newBag.bagName = newBagName
newBag.pockets = []
self.bags.append(newBag)
print(self.bags)
do {
try UserDefaults.standard.setObject(self.bags, forKey: "bagsSavedData")
} catch {
print(error.localizedDescription)
}
self.bagPicker.reloadAllComponents()
}))
self.present(alert, animated: true, completion: nil)
}
@IBAction func DeleteBag(_ sender: Any) {
if (bags.count > 0){
bags.remove(at: bagPicker.selectedRow(inComponent: 0))
bagPicker.selectRow(0, inComponent: 0, animated: true)
bagPicker.reloadAllComponents()
pocketsTable.reloadData()
do {
try UserDefaults.standard.setObject(bags, forKey: "bagsSavedData")
} catch {
print(error.localizedDescription)
}
}
}
@IBAction func SearchBags(_ sender: Any) {
if (bags.count > 0){
var searchQuery:String = ""
let alert = UIAlertController(title: "Enter Search String", message: "", preferredStyle: .alert)
alert.addTextField { (textField) in
textField.text = ""
textField.autocapitalizationType = .words
textField.placeholder = "Search for..."
}
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
let textField = alert?.textFields![0] // Force unwrapping because we know it exists.
print("Text field: \(textField!.text ?? "Search")")
if ((textField!.text ?? "Search") == ""){
return
}
searchQuery = (textField!.text ?? "Search")
var didFindMatches = "Matches found:"
var matchesString = ""
for b in self.bags {
print("searching bag \(b.bagName)")
for p in b.pockets {
print("searching pocket \(p.pocketName)")
for c in p.contents {
if c.containsIgnoringCase(find: searchQuery){
matchesString.append("\n")
matchesString.append("Found Item: \(c)")
matchesString.append("\n")
matchesString.append("In Pocket: \(p.pocketName)")
matchesString.append("\n")
matchesString.append("Of Bag: \(b.bagName)")
matchesString.append("\n")
}
}
}
}
if (matchesString == ""){
didFindMatches = "No Matches Found"
}
let matchesAlert = UIAlertController(title: didFindMatches, message: matchesString, preferredStyle: .alert)
matchesAlert.addAction( UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
print("Ok button tapped")
}))
self.present(matchesAlert, animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
}
@IBAction func AddPocket(_ sender: Any) {
if (bags.count > 0){
var newPocketName:String = ""
let alert = UIAlertController(title: "Enter Pocket Name", message: "", preferredStyle: .alert)
alert.addTextField { (textField) in
textField.text = ""
textField.autocapitalizationType = .words
textField.placeholder = "Pocket Name"
}
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
let textField = alert?.textFields![0] // Force unwrapping because we know it exists.
print("Text field: \(textField!.text ?? "Pocket")")
if ((textField!.text ?? "Pocket") == ""){
return
}
newPocketName = (textField!.text ?? "Pocket")
let newPocket:pocket = pocket.init()
newPocket.pocketName = newPocketName
newPocket.contents = []
self.bags[self.bagPicker.selectedRow(inComponent: 0)].pockets.append(newPocket)
print(self.bags[self.bagPicker.selectedRow(inComponent: 0)].pockets)
do {
try UserDefaults.standard.setObject(self.bags, forKey: "bagsSavedData")
} catch {
print(error.localizedDescription)
}
self.pocketsTable.reloadData()
}))
self.present(alert, animated: true, completion: nil)
}
} }
} }
class ViewController2: UIViewController, UITableViewDataSource, UITableViewDelegate {
var bags:[bag] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
do {
bags = try UserDefaults.standard.getObject(forKey: "bagsSavedData", castTo: [bag].self)
print(bags)
} catch {
print(error.localizedDescription)
}
return bags[passingValues.bag].pockets[passingValues.pocket].contents.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "pocketitem", for: indexPath)
cell.textLabel?.text = bags[passingValues.bag].pockets[passingValues.pocket].contents[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
do {
bags = try UserDefaults.standard.getObject(forKey: "bagsSavedData", castTo: [bag].self)
print(bags)
} catch {
print(error.localizedDescription)
}
print("Delete Item: \(bags[passingValues.bag].pockets[passingValues.pocket].contents[indexPath.row])")
bags[passingValues.bag].pockets[passingValues.pocket].contents.remove(at: indexPath.row)
//tableView.deleteRows(at: [indexPath], with: .fade)
do {
try UserDefaults.standard.setObject(bags, forKey: "bagsSavedData")
} catch {
print(error.localizedDescription)
}
itemsTable.reloadData()
}
}
@IBOutlet var PocketLabel: UILabel!
@IBOutlet var ItemName: UITextField!
@IBOutlet var itemsTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
itemsTable.dataSource = self
itemsTable.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
do {
bags = try UserDefaults.standard.getObject(forKey: "bagsSavedData", castTo: [bag].self)
print(bags)
} catch {
print(error.localizedDescription)
}
itemsTable.reloadData()
PocketLabel.text = bags[passingValues.bag].pockets[passingValues.pocket].pocketName
}
override func viewWillDisappear(_ animated: Bool) {
do {
try UserDefaults.standard.setObject(bags, forKey: "bagsSavedData")
} catch {
print(error.localizedDescription)
}
}
@IBAction func AddItem(_ sender: Any) {
let newItem = ItemName.text
if (newItem != "" && newItem != nil){
bags[passingValues.bag].pockets[passingValues.pocket].contents.append(newItem!)
ItemName.text = ""
do {
try UserDefaults.standard.setObject(bags, forKey: "bagsSavedData")
} catch {
print(error.localizedDescription)
}
itemsTable.reloadData()
}
}
@IBAction func DismissModal(_ sender: Any) {
dismiss(animated: true)
}
@IBAction func DismissKB(_ sender: Any) {
ItemName.resignFirstResponder()
}
}