Skip to content

Commit bc0677e

Browse files
author
FRANCIS HUYNH
committed
Chapter 9 - Part 2
Finished Chapter 9 Including Bronze and Silver challenge.
1 parent d711f2c commit bc0677e

File tree

16 files changed

+894
-18
lines changed

16 files changed

+894
-18
lines changed

Homepwner/Homepwner.xcodeproj/project.pbxproj

+13-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
4E4EB7CA1C460447007CE8CA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4E4EB7C81C460447007CE8CA /* Main.storyboard */; };
1212
4E4EB7CC1C460447007CE8CA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4E4EB7CB1C460447007CE8CA /* Assets.xcassets */; };
1313
4E4EB7CF1C460447007CE8CA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4E4EB7CD1C460447007CE8CA /* LaunchScreen.storyboard */; };
14-
4E4EB7D71C460487007CE8CA /* ItemsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E4EB7D61C460487007CE8CA /* ItemsViewController.swift */; };
14+
4E4EB7DB1C4ACFFA007CE8CA /* Item.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E4EB7DA1C4ACFFA007CE8CA /* Item.swift */; };
15+
4E4EB7DD1C4B55A8007CE8CA /* ItemStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E4EB7DC1C4B55A8007CE8CA /* ItemStore.swift */; };
16+
4E4EB7DF1C4B9DB9007CE8CA /* ItemsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E4EB7DE1C4B9DB9007CE8CA /* ItemsViewController.swift */; };
1517
/* End PBXBuildFile section */
1618

1719
/* Begin PBXFileReference section */
@@ -21,7 +23,9 @@
2123
4E4EB7CB1C460447007CE8CA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
2224
4E4EB7CE1C460447007CE8CA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
2325
4E4EB7D01C460447007CE8CA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
24-
4E4EB7D61C460487007CE8CA /* ItemsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ItemsViewController.swift; path = ../ItemsViewController.swift; sourceTree = "<group>"; };
26+
4E4EB7DA1C4ACFFA007CE8CA /* Item.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = "<group>"; };
27+
4E4EB7DC1C4B55A8007CE8CA /* ItemStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemStore.swift; sourceTree = "<group>"; };
28+
4E4EB7DE1C4B9DB9007CE8CA /* ItemsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemsViewController.swift; sourceTree = "<group>"; };
2529
/* End PBXFileReference section */
2630

2731
/* Begin PBXFrameworksBuildPhase section */
@@ -54,7 +58,9 @@
5458
4E4EB7C31C460447007CE8CA /* Homepwner */ = {
5559
isa = PBXGroup;
5660
children = (
57-
4E4EB7D61C460487007CE8CA /* ItemsViewController.swift */,
61+
4E4EB7DE1C4B9DB9007CE8CA /* ItemsViewController.swift */,
62+
4E4EB7DA1C4ACFFA007CE8CA /* Item.swift */,
63+
4E4EB7DC1C4B55A8007CE8CA /* ItemStore.swift */,
5864
4E4EB7C41C460447007CE8CA /* AppDelegate.swift */,
5965
4E4EB7C81C460447007CE8CA /* Main.storyboard */,
6066
4E4EB7CB1C460447007CE8CA /* Assets.xcassets */,
@@ -135,7 +141,9 @@
135141
isa = PBXSourcesBuildPhase;
136142
buildActionMask = 2147483647;
137143
files = (
138-
4E4EB7D71C460487007CE8CA /* ItemsViewController.swift in Sources */,
144+
4E4EB7DF1C4B9DB9007CE8CA /* ItemsViewController.swift in Sources */,
145+
4E4EB7DB1C4ACFFA007CE8CA /* Item.swift in Sources */,
146+
4E4EB7DD1C4B55A8007CE8CA /* ItemStore.swift in Sources */,
139147
4E4EB7C51C460447007CE8CA /* AppDelegate.swift in Sources */,
140148
);
141149
runOnlyForDeploymentPostprocessing = 0;
@@ -284,6 +292,7 @@
284292
4E4EB7D51C460447007CE8CA /* Release */,
285293
);
286294
defaultConfigurationIsVisible = 0;
295+
defaultConfigurationName = Release;
287296
};
288297
/* End XCConfigurationList section */
289298
};

Homepwner/Homepwner/AppDelegate.swift

+8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1616

1717
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
1818
// Override point for customization after application launch.
19+
20+
// Create the item storage for itemsviewcontroller.
21+
let itemStore = ItemStore()
22+
23+
let itemsController = window!.rootViewController as! ItemsViewController
24+
// QUESTION: Why didn't Xcode autocomplete itemStore? It should know from previous
25+
// downcast that itemsController is ItemsViewController
26+
itemsController.itemStore = itemStore
1927
return true
2028
}
2129

Homepwner/Homepwner/Base.lproj/Main.storyboard

+17-1
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,28 @@
1414
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1515
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
1616
<prototypes>
17-
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="yTN-Se-tnd">
17+
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="EUm-j6-bmI" detailTextLabel="mt3-73-Gew" style="IBUITableViewCellStyleValue1" id="yTN-Se-tnd">
1818
<rect key="frame" x="0.0" y="28" width="600" height="44"/>
1919
<autoresizingMask key="autoresizingMask"/>
2020
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="yTN-Se-tnd" id="DHC-wn-knv">
2121
<rect key="frame" x="0.0" y="0.0" width="600" height="43"/>
2222
<autoresizingMask key="autoresizingMask"/>
23+
<subviews>
24+
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="EUm-j6-bmI">
25+
<rect key="frame" x="15" y="12" width="32" height="20"/>
26+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
27+
<fontDescription key="fontDescription" type="system" pointSize="16"/>
28+
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
29+
<nil key="highlightedColor"/>
30+
</label>
31+
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Detail" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="mt3-73-Gew">
32+
<rect key="frame" x="543" y="12" width="42" height="20"/>
33+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
34+
<fontDescription key="fontDescription" type="system" pointSize="16"/>
35+
<color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="calibratedRGB"/>
36+
<nil key="highlightedColor"/>
37+
</label>
38+
</subviews>
2339
</tableViewCellContentView>
2440
</tableViewCell>
2541
</prototypes>

Homepwner/Homepwner/Item.swift

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// Item.swift
3+
// Homepwner
4+
//
5+
// Created by FRANCIS HUYNH on 1/16/16.
6+
// Copyright © 2016 Fhools. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
// NOTE: Lets figure out what the app needs from NSObject
12+
class Item: NSObject {
13+
var name: String
14+
var valueInDollars: Int
15+
var serialNumber: String?
16+
let dateCreated: NSDate
17+
18+
// NOTE: init is required because not all properties are initialized with default property when declared
19+
init(name: String, serialNumber: String?, valueInDollars: Int) {
20+
self.name = name
21+
self.valueInDollars = valueInDollars
22+
self.dateCreated = NSDate()
23+
24+
// NOTE: This is opposite of C++ where base constructor is always
25+
// initialized first
26+
super.init()
27+
}
28+
29+
convenience init(random: Bool = false) {
30+
if random {
31+
let adjectives = ["Fluffy", "Rusty", "Shiny"]
32+
let nouns = ["Bear", "Spork", "Mac"]
33+
34+
var idx = arc4random_uniform(UInt32(adjectives.count))
35+
let randomAdjective = adjectives[Int(idx)]
36+
37+
idx = arc4random_uniform(UInt32(nouns.count))
38+
let randomNoun = nouns[Int(idx)]
39+
40+
let randomName = "\(randomAdjective) \(randomNoun)"
41+
let randomDollarAmount = Int(arc4random_uniform(100))
42+
let randomSerialNumber = NSUUID().UUIDString.componentsSeparatedByString("-").first!
43+
44+
self.init(name: randomName, serialNumber: randomSerialNumber, valueInDollars: randomDollarAmount)
45+
46+
} else {
47+
self.init(name: "", serialNumber: nil, valueInDollars: 0)
48+
}
49+
}
50+
51+
52+
}

Homepwner/Homepwner/ItemStore.swift

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// ItemStore.swift
3+
// Homepwner
4+
//
5+
// Created by FRANCIS HUYNH on 1/16/16.
6+
// Copyright © 2016 Fhools. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
class ItemStore {
12+
var allItems = [Item]()
13+
14+
func createItem() -> Item {
15+
let newItem = Item(random: true)
16+
allItems.append(newItem)
17+
18+
return newItem;
19+
}
20+
21+
init() {
22+
23+
for _ in 0..<5 {
24+
createItem()
25+
}
26+
27+
28+
29+
}
30+
31+
}
32+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//
2+
// ItemsViewController.swift
3+
// Homepwner
4+
//
5+
// Created by FRANCIS HUYNH on 1/12/16.
6+
// Copyright © 2016 Fhools. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
class ItemsViewController : UITableViewController {
12+
13+
var itemStore: ItemStore!
14+
15+
override func viewDidLoad() {
16+
super.viewDidLoad()
17+
// We want the tableview to appear below the status bar area at the top of
18+
// the screen
19+
let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height
20+
let insets = UIEdgeInsets(top: statusBarHeight, left: 0, bottom: 0, right: 0)
21+
tableView.contentInset = insets
22+
tableView.scrollIndicatorInsets = insets
23+
}
24+
25+
// MARK: UITableViewControllerDataSource
26+
//Note: DataSource is the Model part of MVC
27+
28+
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
29+
let count = itemStore.allItems.count
30+
// Silver challenge: We always have last row be No more items
31+
return count + 1
32+
}
33+
34+
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
35+
// Value1 is big textlabel and detailtextlabel side by side with icon on left as well
36+
// Note: resuseIdentifier is a unique string for each cell that look alike.
37+
38+
// Q: Does framework register this string?
39+
// A: According to BigNerdRanch, the convention is every class that implements UITableViewCell has the name of
40+
// its reuseidentifier be that of the class.
41+
42+
// Q: Why don't we create our own reuseidentifier?
43+
// A: Wrong question, we did set its reuseidentfier when we instantiate it, thats the "reuseidentifier" parameter
44+
45+
// Q: Ok, the reuseidentifier is used by a TableView not UITableViewController, how does that get associated then
46+
// A: UITableViewCell's identifier attribute in the InterfaceBuilder of the "prototype cell"
47+
48+
// Q: Can we have multiple "prototype cells per tableview???"
49+
// A: TableView has a property you can set in interface builder number of prototype cells. Thats how you can set
50+
// the attributes for different type of cells you have from the gui.
51+
52+
53+
// The following is inefficient because it creates a new cell for each row of the tableview data
54+
//let cell = UITableViewCell(style: .Value1, reuseIdentifier: "UITableViewCell")
55+
56+
// The following uses the UITableView's queue of identifier it automatically manages
57+
// Note: If we don't set tableview's prototype cell's attribute to UITableView, it wouldn't have known!
58+
let cell = tableView.dequeueReusableCellWithIdentifier("UITableViewCell", forIndexPath: indexPath)
59+
if indexPath.row < itemStore.allItems.count {
60+
let item = itemStore.allItems[indexPath.row]
61+
cell.textLabel?.text = item.name
62+
cell.detailTextLabel?.text = "$\(item.valueInDollars)"
63+
} else {
64+
cell.textLabel?.text = "No more items"
65+
cell.detailTextLabel?.text = ""
66+
}
67+
68+
return cell
69+
}
70+
71+
72+
}

Homepwner/ItemsViewController.swift

-13
This file was deleted.

0 commit comments

Comments
 (0)