├── .gitignore
├── LICENSE
├── README.md
├── art
├── Xcode.png
├── cs193p-Lecture-01.png
├── cs193p.jpg
├── iTunesU.png
└── play.png
├── democode
├── Archive
│ ├── Cassini-L7.zip
│ ├── Cassini-L8.zip
│ ├── DropIt-L14.zip
│ ├── FaceIt-L13.zip
│ ├── FaceIt-L4.zip
│ ├── FaceIt-L5.zip
│ ├── FaceIt-L6.zip
│ ├── Pollster-L16.zip
│ ├── Smashtag-L11.zip
│ ├── Smashtag-L9.zip
│ └── Trax-L18.zip
├── Cassini-L7
│ ├── Cassini.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── Cassini
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── DemoURL.swift
│ │ ├── ImageViewController.swift
│ │ └── Info.plist
├── Cassini-L8
│ ├── Cassini.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── Cassini
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── CassiniViewController.swift
│ │ ├── DemoURL.swift
│ │ ├── ImageViewController.swift
│ │ └── Info.plist
├── DropIt-L14
│ ├── DropIt.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── DropIt
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── DropItView.swift
│ │ ├── DropItViewController.swift
│ │ ├── FallingObjectBehavior.swift
│ │ ├── Info.plist
│ │ ├── NamedBezierPathsView.swift
│ │ └── UIKit Extensions.swift
├── FaceIt-L13
│ ├── FaceIt.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── FaceIt
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── BlinkingFaceViewController.swift
│ │ ├── EmotionsViewController.swift
│ │ ├── EyeView.swift
│ │ ├── FaceView.swift
│ │ ├── FaceViewController.swift
│ │ ├── FacialExpression.swift
│ │ ├── Info.plist
│ │ └── VCL.swift
├── FaceIt-L4
│ ├── FaceIt.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── FaceIt
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── FaceView.swift
│ │ ├── FaceViewController.swift
│ │ └── Info.plist
├── FaceIt-L5
│ ├── FaceIt.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── FaceIt
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── FaceView.swift
│ │ ├── FaceViewController.swift
│ │ ├── FacialExpression.swift
│ │ └── Info.plist
├── FaceIt-L6
│ ├── FaceIt.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── FaceIt
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── EmotionsViewController.swift
│ │ ├── FaceView.swift
│ │ ├── FaceViewController.swift
│ │ ├── FacialExpression.swift
│ │ ├── Info.plist
│ │ └── VCL.swift
├── Pollster-L16
│ ├── Pollster.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── Pollster
│ │ ├── AllQandAsTableViewController.swift
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── CloudKitExtensions.swift
│ │ ├── CloudQandATableViewController.swift
│ │ ├── Info.plist
│ │ ├── Pollster.entitlements
│ │ ├── QandAAccessoryTableViewController.swift
│ │ ├── QandATableViewController.swift
│ │ └── TextTableViewController.swift
├── README.md
├── Smashtag-L11
│ ├── Smashtag.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── Smashtag
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── CoreDataTableViewController.swift
│ │ ├── Info.plist
│ │ ├── Model.xcdatamodeld
│ │ └── Model.xcdatamodel
│ │ │ └── contents
│ │ ├── Tweet+CoreDataProperties.swift
│ │ ├── Tweet.swift
│ │ ├── TweetTableViewCell.swift
│ │ ├── TweetTableViewController.swift
│ │ ├── TweetersTableViewController.swift
│ │ ├── TwitterUser+CoreDataProperties.swift
│ │ └── TwitterUser.swift
├── Smashtag-L9
│ ├── Smashtag
│ │ ├── Smashtag.xcodeproj
│ │ │ ├── project.pbxproj
│ │ │ └── project.xcworkspace
│ │ │ │ └── contents.xcworkspacedata
│ │ └── Smashtag
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ ├── TweetTableViewCell.swift
│ │ │ └── TweetTableViewController.swift
│ └── Twitter
│ │ ├── Twitter.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── Twitter
│ │ ├── Info.plist
│ │ ├── MediaItem.swift
│ │ ├── Request.swift
│ │ ├── Tweet.swift
│ │ ├── Twitter.h
│ │ └── User.swift
└── Trax-L18
│ ├── Trax.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── Trax
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── EditWaypointViewController.swift
│ ├── GPX.swift
│ ├── GPXViewController.swift
│ ├── ImageViewController.swift
│ ├── Info.plist
│ └── MKGPX.swift
├── problemsets
├── Programming_Project_1_Calculator.pdf
├── Programming_Project_2_Calculator_Brain.pdf
├── Programming_Project_3_Graphic_Calculator.pdf
├── Programming_Project_4_Smashtag_Mentions.pdf
├── Programming_Project_5_Smashtag_Ment.pdf
├── Programming_Project_6_Animation.pdf
└── assignment-1
│ ├── Art
│ ├── AppIcon
│ │ ├── AppIcon.png
│ │ ├── AppIcon.xcf
│ │ └── IconSet
│ │ │ ├── Icon-40.png
│ │ │ ├── Icon-40@2x.png
│ │ │ ├── Icon-40@3x.png
│ │ │ ├── Icon-60.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-72.png
│ │ │ ├── Icon-72@2x.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-83.5@2x.png
│ │ │ ├── Icon-Small-50.png
│ │ │ ├── Icon-Small-50@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ ├── Icon-Small@3x.png
│ │ │ ├── Icon.png
│ │ │ ├── Icon@2x.png
│ │ │ ├── iTunesArtwork.png
│ │ │ └── iTunesArtwork@2x.png
│ └── Screenshot
│ │ ├── Calculator00.gif
│ │ ├── Calculator01.gif
│ │ ├── Calculator02.gif
│ │ ├── Calculator03.gif
│ │ ├── Calculator04.gif
│ │ ├── Calculator05.gif
│ │ ├── Calculator06.gif
│ │ └── Calculator07.gif
│ ├── CONTRIBUTING.md
│ ├── Calculator
│ ├── Calculator.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── Calculator
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-40.png
│ │ │ ├── Icon-40@2x-1.png
│ │ │ ├── Icon-40@2x.png
│ │ │ ├── Icon-40@3x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-83.5@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x-1.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ └── Icon-Small@3x.png
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── CalculatorBrain.swift
│ │ ├── Info.plist
│ │ ├── RoundedButton.swift
│ │ └── ViewController.swift
│ ├── LICENSE
│ └── README.md
├── reading
├── Reading_1_Intro_to_Swift.pdf
├── Reading_2_More_Swift.pdf
└── Reading_3_The_Rest_of_Swift.pdf
└── slides
├── Lecture-1-Slides.pdf
├── Lecture-10-Slides.pdf
├── Lecture-11-Slides.pdf
├── Lecture-12-Slides.pdf
├── Lecture-13-Slides.pdf
├── Lecture-14-Slides.pdf
├── Lecture-15-Slides.pdf
├── Lecture-16-Slides.pdf
├── Lecture-17-Slides.pdf
├── Lecture-18-Slides.pdf
├── Lecture-2-Slides.pdf
├── Lecture-3-Slides.pdf
├── Lecture-4-Slides.pdf
├── Lecture-5-Slides.pdf
├── Lecture-6-Slides.pdf
├── Lecture-7-Slides.pdf
├── Lecture-8-Slides.pdf
└── Lecture-9-Slides.pdf
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata
19 |
20 | ## Other
21 | *.xccheckout
22 | *.moved-aside
23 | *.xcuserstate
24 | *.xcscmblueprint
25 |
26 | ## Obj-C/Swift specific
27 | *.hmap
28 | *.ipa
29 |
30 | ## Mac Specific
31 | .DS_Store
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | # Packages/
41 | .build/
42 |
43 | # CocoaPods
44 | #
45 | # We recommend against adding the Pods directory to your .gitignore. However
46 | # you should judge for yourself, the pros and cons are mentioned at:
47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
48 | #
49 | # Pods/
50 |
51 | # Carthage
52 | #
53 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
54 | # Carthage/Checkouts
55 |
56 | Carthage/Build
57 |
58 | # fastlane
59 | #
60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
61 | # screenshots whenever they are needed.
62 | # For more information about the recommended setup visit:
63 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md
64 |
65 | fastlane/report.xml
66 | fastlane/screenshots
67 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Dulio Denis
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/art/Xcode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/art/Xcode.png
--------------------------------------------------------------------------------
/art/cs193p-Lecture-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/art/cs193p-Lecture-01.png
--------------------------------------------------------------------------------
/art/cs193p.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/art/cs193p.jpg
--------------------------------------------------------------------------------
/art/iTunesU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/art/iTunesU.png
--------------------------------------------------------------------------------
/art/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/art/play.png
--------------------------------------------------------------------------------
/democode/Archive/Cassini-L7.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/Cassini-L7.zip
--------------------------------------------------------------------------------
/democode/Archive/Cassini-L8.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/Cassini-L8.zip
--------------------------------------------------------------------------------
/democode/Archive/DropIt-L14.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/DropIt-L14.zip
--------------------------------------------------------------------------------
/democode/Archive/FaceIt-L13.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/FaceIt-L13.zip
--------------------------------------------------------------------------------
/democode/Archive/FaceIt-L4.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/FaceIt-L4.zip
--------------------------------------------------------------------------------
/democode/Archive/FaceIt-L5.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/FaceIt-L5.zip
--------------------------------------------------------------------------------
/democode/Archive/FaceIt-L6.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/FaceIt-L6.zip
--------------------------------------------------------------------------------
/democode/Archive/Pollster-L16.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/Pollster-L16.zip
--------------------------------------------------------------------------------
/democode/Archive/Smashtag-L11.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/Smashtag-L11.zip
--------------------------------------------------------------------------------
/democode/Archive/Smashtag-L9.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/Smashtag-L9.zip
--------------------------------------------------------------------------------
/democode/Archive/Trax-L18.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/democode/Archive/Trax-L18.zip
--------------------------------------------------------------------------------
/democode/Cassini-L7/Cassini.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/Cassini-L7/Cassini/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Cassini
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/democode/Cassini-L7/Cassini/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/democode/Cassini-L7/Cassini/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/Cassini-L7/Cassini/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/democode/Cassini-L7/Cassini/DemoURL.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URL.swift
3 | //
4 | // Created by CS193p Instructor.
5 | // Copyright (c) 2016 Stanford University. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | struct DemoURL
11 | {
12 | static let Stanford = "http://comm.stanford.edu/wp-content/uploads/2013/01/stanford-campus.png"
13 |
14 | static let NASA = [
15 | "Cassini" : "http://www.jpl.nasa.gov/images/cassini/20090202/pia03883-full.jpg",
16 | "Earth" : "http://www.nasa.gov/sites/default/files/wave_earth_mosaic_3.jpg",
17 | "Saturn" : "http://www.nasa.gov/sites/default/files/saturn_collage.jpg"
18 | ]
19 |
20 | static func NASAImageNamed(imageName: String?) -> NSURL? {
21 | if let urlstring = NASA[imageName ?? ""] {
22 | return NSURL(string: urlstring)
23 | } else {
24 | return nil
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/democode/Cassini-L7/Cassini/ImageViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImageViewController.swift
3 | // Cassini
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ImageViewController: UIViewController
12 | {
13 | var imageURL: NSURL? {
14 | didSet {
15 | image = nil
16 | fetchImage()
17 | }
18 | }
19 |
20 | private func fetchImage() {
21 | if let url = imageURL {
22 | if let imageData = NSData(contentsOfURL: url) {
23 | image = UIImage(data: imageData)
24 | }
25 | }
26 | }
27 |
28 | @IBOutlet weak var scrollView: UIScrollView! {
29 | didSet {
30 | scrollView.contentSize = imageView.frame.size
31 | }
32 | }
33 |
34 | private var imageView = UIImageView()
35 |
36 | private var image: UIImage? {
37 | get {
38 | return imageView.image
39 | }
40 | set {
41 | imageView.image = newValue
42 | imageView.sizeToFit()
43 | scrollView?.contentSize = imageView.frame.size
44 | }
45 | }
46 |
47 | override func viewDidLoad() {
48 | super.viewDidLoad()
49 | scrollView.addSubview(imageView)
50 | imageURL = NSURL(string: DemoURL.Stanford)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/democode/Cassini-L7/Cassini/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | NSAppTransportSecurity
40 |
41 | NSAllowsArbitraryLoads
42 |
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/democode/Cassini-L8/Cassini.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/Cassini-L8/Cassini/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Cassini
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/democode/Cassini-L8/Cassini/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/democode/Cassini-L8/Cassini/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/Cassini-L8/Cassini/CassiniViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CassiniViewController.swift
3 | // Cassini
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CassiniViewController: UIViewController, UISplitViewControllerDelegate
12 | {
13 | // this is just our normal "put constants in a struct" thing
14 | // but we call it Storyboard, because all the constants in it
15 | // are strings in our Storyboard
16 |
17 | private struct Storyboard {
18 | static let ShowImageSegue = "Show Image"
19 | }
20 |
21 | // prepare for segue is called
22 | // even if we invoke the segue from code using performSegue (see below)
23 |
24 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
25 | if segue.identifier == Storyboard.ShowImageSegue {
26 | if let ivc = segue.destinationViewController.contentViewController as? ImageViewController {
27 | let imageName = (sender as? UIButton)?.currentTitle
28 | ivc.imageURL = DemoURL.NASAImageNamed(imageName)
29 | ivc.title = imageName
30 | }
31 | }
32 | }
33 |
34 | // we changed the buttons to this target/action method
35 | // so that we could either
36 | // a) just set our imageURL in the detail if we're in a split view, or
37 | // b) cause the segue to happen from code with performSegue
38 | // to make the latter work, we had to create a segue in our storyboard
39 | // that was ctrl-dragged from the view controller icon (orange one at the top)
40 |
41 | @IBAction func showImage(sender: UIButton) {
42 | if let ivc = splitViewController?.viewControllers.last?.contentViewController as? ImageViewController {
43 | let imageName = sender.currentTitle
44 | ivc.imageURL = DemoURL.NASAImageNamed(imageName)
45 | ivc.title = imageName
46 | } else {
47 | performSegueWithIdentifier(Storyboard.ShowImageSegue, sender: sender)
48 | }
49 | }
50 |
51 | // if we are in a split view, we set ourselves as its delegate
52 | // this is so we can prevent an empty detail from collapsing on top of our master
53 | // see split view delegate method below
54 |
55 | override func viewDidLoad() {
56 | super.viewDidLoad()
57 | splitViewController?.delegate = self
58 | }
59 |
60 | // this method lets the split view's delegate
61 | // collapse the detail on top of the master when it's the detail's time to appear
62 | // this method returns whether we (the delegate) handled doing this
63 | // we don't want an empty detail to collapse on top of our master
64 | // so if the detail is an empty ImageViewController, we return true
65 | // (which tells the split view controller that we handled the collapse)
66 | // of course, we didn't actually handle it, we did nothing
67 | // but that's exactly what we want (i.e. no collapse if the detail ivc is empty)
68 |
69 | func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool
70 | {
71 | if primaryViewController.contentViewController == self {
72 | if let ivc = secondaryViewController.contentViewController as? ImageViewController where ivc.imageURL == nil {
73 | return true
74 | }
75 | }
76 | return false
77 | }
78 | }
79 |
80 | // a little helper extension
81 | // which either returns the view controller you send it to
82 | // or, if you send it to a UINavigationController,
83 | // it returns its visibleViewController
84 | // (if any, otherwise the UINavigationController itself)
85 |
86 | extension UIViewController {
87 | var contentViewController: UIViewController {
88 | if let navcon = self as? UINavigationController {
89 | return navcon.visibleViewController ?? self
90 | } else {
91 | return self
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/democode/Cassini-L8/Cassini/DemoURL.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URL.swift
3 | //
4 | // Created by CS193p Instructor.
5 | // Copyright (c) 2016 Stanford University. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | struct DemoURL
11 | {
12 | static let Stanford = "http://comm.stanford.edu/wp-content/uploads/2013/01/stanford-campus.png"
13 |
14 | static let NASA = [
15 | "Cassini" : "http://www.jpl.nasa.gov/images/cassini/20090202/pia03883-full.jpg",
16 | "Earth" : "http://www.nasa.gov/sites/default/files/wave_earth_mosaic_3.jpg",
17 | "Saturn" : "http://www.nasa.gov/sites/default/files/saturn_collage.jpg"
18 | ]
19 |
20 | static func NASAImageNamed(imageName: String?) -> NSURL? {
21 | if let urlstring = NASA[imageName ?? ""] {
22 | return NSURL(string: urlstring)
23 | } else {
24 | return nil
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/democode/Cassini-L8/Cassini/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | NSAppTransportSecurity
40 |
41 | NSAllowsArbitraryLoads
42 |
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // DropIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt/DropItViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DropItViewController.swift
3 | // DropIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class DropItViewController: UIViewController
12 | {
13 | @IBOutlet weak var gameView: DropItView! {
14 | didSet {
15 | gameView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(addDrop(_:))))
16 | gameView.addGestureRecognizer(UIPanGestureRecognizer(target: gameView, action: #selector(DropItView.grabDrop(_:))))
17 | gameView.realGravity = true
18 | }
19 | }
20 |
21 | func addDrop(recognizer: UITapGestureRecognizer) {
22 | if recognizer.state == .Ended {
23 | gameView.addDrop()
24 | }
25 | }
26 |
27 | override func viewDidAppear(animated: Bool) {
28 | super.viewDidAppear(animated)
29 | gameView.animating = true
30 | }
31 |
32 | override func viewWillDisappear(animated: Bool) {
33 | super.viewWillDisappear(animated)
34 | gameView.animating = false
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt/FallingObjectBehavior.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FallingObjectBehavior.swift
3 | // DropIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FallingObjectBehavior: UIDynamicBehavior
12 | {
13 | let gravity = UIGravityBehavior()
14 |
15 | private let collider: UICollisionBehavior = {
16 | let collider = UICollisionBehavior()
17 | collider.translatesReferenceBoundsIntoBoundary = true
18 | return collider
19 | }()
20 |
21 | private let itemBehavior: UIDynamicItemBehavior = {
22 | let dib = UIDynamicItemBehavior()
23 | dib.allowsRotation = true
24 | dib.elasticity = 0.75
25 | return dib
26 | }()
27 |
28 | func addBarrier(path: UIBezierPath, named name: String) {
29 | collider.removeBoundaryWithIdentifier(name)
30 | collider.addBoundaryWithIdentifier(name, forPath: path)
31 | }
32 |
33 | override init() {
34 | super.init()
35 | addChildBehavior(gravity)
36 | addChildBehavior(collider)
37 | addChildBehavior(itemBehavior)
38 | }
39 |
40 | func addItem(item: UIDynamicItem) {
41 | gravity.addItem(item)
42 | collider.addItem(item)
43 | itemBehavior.addItem(item)
44 | }
45 |
46 | func removeItem(item: UIDynamicItem) {
47 | gravity.removeItem(item)
48 | collider.removeItem(item)
49 | itemBehavior.removeItem(item)
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt/NamedBezierPathsView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NamedBezierPathsView.swift
3 | // DropIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class NamedBezierPathsView: UIView
12 | {
13 | var bezierPaths = [String:UIBezierPath]() { didSet { setNeedsDisplay() } }
14 |
15 | override func drawRect(rect: CGRect) {
16 | for (_, path) in bezierPaths {
17 | path.stroke()
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/democode/DropIt-L14/DropIt/UIKit Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extensions.swift
3 | // DropIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension CGFloat {
12 | static func random(max: Int) -> CGFloat {
13 | return CGFloat(arc4random() % UInt32(max))
14 | }
15 | }
16 |
17 | extension UIColor {
18 | class var random: UIColor {
19 | switch arc4random()%5 {
20 | case 0: return UIColor.greenColor()
21 | case 1: return UIColor.blueColor()
22 | case 2: return UIColor.orangeColor()
23 | case 3: return UIColor.redColor()
24 | case 4: return UIColor.purpleColor()
25 | default: return UIColor.blackColor()
26 | }
27 | }
28 | }
29 |
30 | extension CGRect {
31 | var mid: CGPoint { return CGPoint(x: midX, y: midY) }
32 | var upperLeft: CGPoint { return CGPoint(x: minX, y: minY) }
33 | var lowerLeft: CGPoint { return CGPoint(x: minX, y: maxY) }
34 | var upperRight: CGPoint { return CGPoint(x: maxX, y: minY) }
35 | var lowerRight: CGPoint { return CGPoint(x: maxX, y: maxY) }
36 |
37 | init(center: CGPoint, size: CGSize) {
38 | let upperLeft = CGPoint(x: center.x-size.width/2, y: center.y-size.height/2)
39 | self.init(origin: upperLeft, size: size)
40 | }
41 | }
42 |
43 | extension UIView {
44 | func hitTest(p: CGPoint) -> UIView? {
45 | return hitTest(p, withEvent: nil)
46 | }
47 | }
48 |
49 | extension UIBezierPath {
50 | class func lineFrom(from: CGPoint, to: CGPoint) -> UIBezierPath {
51 | let path = UIBezierPath()
52 | path.moveToPoint(from)
53 | path.addLineToPoint(to)
54 | return path
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/democode/FaceIt-L13/FaceIt.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/FaceIt-L13/FaceIt/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/democode/FaceIt-L13/FaceIt/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/democode/FaceIt-L13/FaceIt/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/FaceIt-L13/FaceIt/BlinkingFaceViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BlinkingFaceViewController.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BlinkingFaceViewController: FaceViewController
12 | {
13 | var blinking: Bool = false {
14 | didSet {
15 | startBlink()
16 | }
17 | }
18 |
19 | private struct BlinkRate {
20 | static let ClosedDuration = 0.4
21 | static let OpenDuration = 2.5
22 | }
23 |
24 | func startBlink() {
25 | if blinking {
26 | faceView.eyesOpen = false
27 | NSTimer.scheduledTimerWithTimeInterval(
28 | BlinkRate.ClosedDuration,
29 | target: self, selector: #selector(BlinkingFaceViewController.endBlink),
30 | userInfo: nil,
31 | repeats: false
32 | )
33 | }
34 | }
35 |
36 | func endBlink() {
37 | faceView.eyesOpen = true
38 | NSTimer.scheduledTimerWithTimeInterval(
39 | BlinkRate.OpenDuration,
40 | target: self, selector: #selector(BlinkingFaceViewController.startBlink),
41 | userInfo: nil,
42 | repeats: false
43 | )
44 | }
45 |
46 | override func viewDidAppear(animated: Bool) {
47 | super.viewDidAppear(animated)
48 | blinking = true
49 | }
50 |
51 | override func viewWillDisappear(animated: Bool) {
52 | super.viewWillDisappear(animated)
53 | blinking = false
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/democode/FaceIt-L13/FaceIt/EmotionsViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EmotionsViewController.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class EmotionsViewController: UIViewController
12 | {
13 | private let emotionalFaces: Dictionary = [
14 | "angry" : FacialExpression(eyes: .Closed, eyeBrows: .Furrowed, mouth: .Frown),
15 | "happy" : FacialExpression(eyes: .Open, eyeBrows: .Normal, mouth: .Smile),
16 | "worried" : FacialExpression(eyes: .Open, eyeBrows: .Relaxed, mouth: .Smirk),
17 | "mischievious" : FacialExpression(eyes: .Open, eyeBrows: .Furrowed, mouth: .Grin)
18 | ]
19 |
20 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
21 | var destinationvc = segue.destinationViewController
22 | if let navcon = destinationvc as? UINavigationController {
23 | destinationvc = navcon.visibleViewController ?? destinationvc
24 | }
25 | if let facevc = destinationvc as? FaceViewController {
26 | if let identifier = segue.identifier {
27 | if let expression = emotionalFaces[identifier] {
28 | facevc.expression = expression
29 | if let sendingButton = sender as? UIButton {
30 | facevc.navigationItem.title = sendingButton.currentTitle
31 | }
32 | }
33 | }
34 | }
35 | }
36 |
37 | // let instance = getEmotionsMVCinstanceCount()
38 | }
39 |
--------------------------------------------------------------------------------
/democode/FaceIt-L13/FaceIt/EyeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EyeView.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2015 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class EyeView: UIView
12 | {
13 | var lineWidth: CGFloat = 5.0 { didSet { setNeedsDisplay() } }
14 | var color: UIColor = UIColor.blueColor() { didSet { setNeedsDisplay() } }
15 |
16 | var _eyesOpen: Bool = true { didSet { setNeedsDisplay() } }
17 |
18 | var eyesOpen: Bool {
19 | get {
20 | return _eyesOpen
21 | }
22 | set {
23 | UIView.transitionWithView(
24 | self,
25 | duration: 0.2,
26 | options: [.TransitionFlipFromTop,.CurveLinear],
27 | animations: {
28 | self._eyesOpen = newValue
29 | },
30 | completion: nil
31 | )
32 | }
33 | }
34 |
35 | override func drawRect(rect: CGRect)
36 | {
37 | var path: UIBezierPath!
38 |
39 | if eyesOpen {
40 | path = UIBezierPath(ovalInRect: bounds.insetBy(dx: lineWidth/2, dy: lineWidth/2))
41 | } else {
42 | path = UIBezierPath()
43 | path.moveToPoint(CGPoint(x: bounds.minX, y: bounds.midY))
44 | path.addLineToPoint(CGPoint(x: bounds.maxX, y: bounds.midY))
45 | }
46 |
47 | path.lineWidth = lineWidth
48 | color.setStroke()
49 | path.stroke()
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/democode/FaceIt-L13/FaceIt/FacialExpression.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FacialExpression.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2015-16 Stanford University. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // UI-independent representation of a facial expression
12 |
13 | struct FacialExpression
14 | {
15 | enum Eyes: Int {
16 | case Open
17 | case Closed
18 | case Squinting
19 | }
20 |
21 | enum EyeBrows: Int {
22 | case Relaxed
23 | case Normal
24 | case Furrowed
25 |
26 | func moreRelaxedBrow() -> EyeBrows {
27 | return EyeBrows(rawValue: rawValue - 1) ?? .Relaxed
28 | }
29 | func moreFurrowedBrow() -> EyeBrows {
30 | return EyeBrows(rawValue: rawValue + 1) ?? .Furrowed
31 | }
32 | }
33 |
34 | enum Mouth: Int {
35 | case Frown
36 | case Smirk
37 | case Neutral
38 | case Grin
39 | case Smile
40 |
41 | func sadderMouth() -> Mouth {
42 | return Mouth(rawValue: rawValue - 1) ?? .Frown
43 | }
44 | func happierMouth() -> Mouth {
45 | return Mouth(rawValue: rawValue + 1) ?? .Smile
46 | }
47 | }
48 |
49 | var eyes: Eyes
50 | var eyeBrows: EyeBrows
51 | var mouth: Mouth
52 | }
53 |
--------------------------------------------------------------------------------
/democode/FaceIt-L13/FaceIt/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/democode/FaceIt-L4/FaceIt.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/FaceIt-L4/FaceIt/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/democode/FaceIt-L4/FaceIt/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/democode/FaceIt-L4/FaceIt/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/FaceIt-L4/FaceIt/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/democode/FaceIt-L4/FaceIt/FaceView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FaceView.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FaceView: UIView
12 | {
13 | var scale: CGFloat = 0.90
14 | var mouthCurvature: Double = 1.0 // 1 full smile, -1 full frown
15 |
16 | private var skullRadius: CGFloat {
17 | return min(bounds.size.width, bounds.size.height) / 2 * scale
18 | }
19 | private var skullCenter: CGPoint {
20 | return CGPoint(x: bounds.midX, y: bounds.midY)
21 | }
22 |
23 | private struct Ratios {
24 | static let SkullRadiusToEyeOffset: CGFloat = 3
25 | static let SkullRadiusToEyeRadius: CGFloat = 10
26 | static let SkullRadiusToMouthWidth: CGFloat = 1
27 | static let SkullRadiusToMouthHeight: CGFloat = 3
28 | static let SkullRadiusToMouthOffset: CGFloat = 3
29 | }
30 |
31 | private enum Eye {
32 | case Left
33 | case Right
34 | }
35 |
36 | private func pathForCircleCenteredAtPoint(midPoint: CGPoint, withRadius radius: CGFloat) -> UIBezierPath
37 | {
38 | let path = UIBezierPath(
39 | arcCenter: midPoint,
40 | radius: radius,
41 | startAngle: 0.0,
42 | endAngle: CGFloat(2*M_PI),
43 | clockwise: false
44 | )
45 | path.lineWidth = 5.0
46 | return path
47 | }
48 |
49 | private func getEyeCenter(eye: Eye) -> CGPoint
50 | {
51 | let eyeOffset = skullRadius / Ratios.SkullRadiusToEyeOffset
52 | var eyeCenter = skullCenter
53 | eyeCenter.y -= eyeOffset
54 | switch eye {
55 | case .Left: eyeCenter.x -= eyeOffset
56 | case .Right: eyeCenter.x += eyeOffset
57 | }
58 | return eyeCenter
59 | }
60 |
61 | private func pathForEye(eye: Eye) -> UIBezierPath
62 | {
63 | let eyeRadius = skullRadius / Ratios.SkullRadiusToEyeRadius
64 | let eyeCenter = getEyeCenter(eye)
65 | return pathForCircleCenteredAtPoint(eyeCenter, withRadius: eyeRadius)
66 | }
67 |
68 | private func pathForMouth() -> UIBezierPath
69 | {
70 | let mouthWidth = skullRadius / Ratios.SkullRadiusToMouthWidth
71 | let mouthHeight = skullRadius / Ratios.SkullRadiusToMouthHeight
72 | let mouthOffset = skullRadius / Ratios.SkullRadiusToMouthOffset
73 |
74 | let mouthRect = CGRect(x: skullCenter.x - mouthWidth/2, y: skullCenter.y + mouthOffset, width: mouthWidth, height: mouthHeight)
75 |
76 | let smileOffset = CGFloat(max(-1, min(mouthCurvature, 1))) * mouthRect.height
77 | let start = CGPoint(x: mouthRect.minX, y: mouthRect.minY)
78 | let end = CGPoint(x: mouthRect.maxX, y: mouthRect.minY)
79 | let cp1 = CGPoint(x: mouthRect.minX + mouthRect.width / 3, y: mouthRect.minY + smileOffset)
80 | let cp2 = CGPoint(x: mouthRect.maxX - mouthRect.width / 3, y: mouthRect.minY + smileOffset)
81 |
82 | let path = UIBezierPath()
83 | path.moveToPoint(start)
84 | path.addCurveToPoint(end, controlPoint1: cp1, controlPoint2: cp2)
85 | path.lineWidth = 5.0
86 |
87 | return path
88 | }
89 |
90 | override func drawRect(rect: CGRect)
91 | {
92 | UIColor.blueColor().set()
93 | pathForCircleCenteredAtPoint(skullCenter, withRadius: skullRadius).stroke()
94 | pathForEye(.Left).stroke()
95 | pathForEye(.Right).stroke()
96 | pathForMouth().stroke()
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/democode/FaceIt-L4/FaceIt/FaceViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FaceViewController: UIViewController
12 | {
13 | }
14 |
--------------------------------------------------------------------------------
/democode/FaceIt-L4/FaceIt/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/democode/FaceIt-L5/FaceIt.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/FaceIt-L5/FaceIt/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/democode/FaceIt-L5/FaceIt/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/democode/FaceIt-L5/FaceIt/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/FaceIt-L5/FaceIt/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/democode/FaceIt-L5/FaceIt/FaceViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FaceViewController: UIViewController
12 | {
13 | // MARK: Model
14 |
15 | var expression = FacialExpression(eyes: .Closed, eyeBrows: .Relaxed, mouth: .Smirk) {
16 | didSet {
17 | updateUI() // Model changed, so update the View
18 | }
19 | }
20 |
21 | // MARK: View
22 |
23 | // the didSet here is called only once
24 | // when the outlet is connected up by iOS
25 | @IBOutlet weak var faceView: FaceView! {
26 | didSet {
27 | faceView.addGestureRecognizer(UIPinchGestureRecognizer(
28 | target: faceView, action: #selector(FaceView.changeScale(_:))
29 | ))
30 |
31 | let happierSwipeGestureRecognizer = UISwipeGestureRecognizer(
32 | target: self, action: #selector(FaceViewController.increaseHappiness)
33 | )
34 | happierSwipeGestureRecognizer.direction = .Up
35 | faceView.addGestureRecognizer(happierSwipeGestureRecognizer)
36 |
37 | let sadderSwipeGestureRecognizer = UISwipeGestureRecognizer(
38 | target: self, action: #selector(FaceViewController.decreaseHappiness)
39 | )
40 | sadderSwipeGestureRecognizer.direction = .Down
41 | faceView.addGestureRecognizer(sadderSwipeGestureRecognizer)
42 |
43 | // ADDED AFTER LECTURE 5
44 | faceView.addGestureRecognizer(UIRotationGestureRecognizer(
45 | target: self, action: #selector(FaceViewController.changeBrows(_:))
46 | ))
47 |
48 | updateUI() // View connected for first time, update it from Model
49 | }
50 | }
51 |
52 | // here the Controller is doing its job
53 | // of interpreting the Model (expression) for the View (faceView)
54 |
55 | private func updateUI() {
56 | switch expression.eyes {
57 | case .Open: faceView.eyesOpen = true
58 | case .Closed: faceView.eyesOpen = false
59 | case .Squinting: faceView.eyesOpen = false
60 | }
61 | faceView.mouthCurvature = mouthCurvatures[expression.mouth] ?? 0.0
62 | faceView.eyeBrowTilt = eyeBrowTilts[expression.eyeBrows] ?? 0.0
63 | }
64 |
65 | private var mouthCurvatures = [FacialExpression.Mouth.Frown:-1.0,.Grin:0.5,.Smile:1.0,.Smirk:-0.5,.Neutral:0.0 ]
66 | private var eyeBrowTilts = [FacialExpression.EyeBrows.Relaxed:0.5,.Furrowed:-0.5,.Normal:0.0]
67 |
68 | // MARK: Gesture Handlers
69 |
70 | // gesture handler for swipe to increase happiness
71 | // changes the Model (which will, in turn, updateUI())
72 | func increaseHappiness() {
73 | expression.mouth = expression.mouth.happierMouth()
74 | }
75 |
76 | // gesture handler for swipe to decrease happiness
77 | // changes the Model (which will, in turn, updateUI())
78 | func decreaseHappiness() {
79 | expression.mouth = expression.mouth.sadderMouth()
80 | }
81 |
82 | // gesture handler for taps
83 | //
84 | // toggles the open/closed state of the eyes in the Model
85 | // and all changes to the Model automatically updateUI()
86 | // (see the didSet for the Model var expression above)
87 | // so our faceView will also change its eyes
88 | //
89 | // this handler was added directly in the storyboard
90 | // by dragging a UITapGestureHandler onto the faceView
91 | // then ctrl-dragging from the tap gesture
92 | // (at the top of the scene in the storyboard)
93 | // here to our Controller
94 | // (so there's no need to call addGestureRecognizer)
95 |
96 | @IBAction func toggleEyes(recognizer: UITapGestureRecognizer) {
97 | if recognizer.state == .Ended {
98 | switch expression.eyes {
99 | case .Open: expression.eyes = .Closed
100 | case .Closed: expression.eyes = .Open
101 | case .Squinting: break // we don't know how to toggle "Squinting"
102 | }
103 | }
104 | }
105 |
106 | // ADDED AFTER LECTURE 5
107 | // gesture handler to change the Model's brows with a rotation gesture
108 | func changeBrows(recognizer: UIRotationGestureRecognizer) {
109 | switch recognizer.state {
110 | case .Changed,.Ended:
111 | if recognizer.rotation > CGFloat(M_PI/4) {
112 | expression.eyeBrows = expression.eyeBrows.moreRelaxedBrow()
113 | recognizer.rotation = 0.0
114 | } else if recognizer.rotation < -CGFloat(M_PI/4) {
115 | expression.eyeBrows = expression.eyeBrows.moreFurrowedBrow()
116 | recognizer.rotation = 0.0
117 | }
118 | default:
119 | break
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/democode/FaceIt-L5/FaceIt/FacialExpression.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FacialExpression.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2015-16 Stanford University. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // UI-independent representation of a facial expression
12 |
13 | struct FacialExpression
14 | {
15 | enum Eyes: Int {
16 | case Open
17 | case Closed
18 | case Squinting
19 | }
20 |
21 | enum EyeBrows: Int {
22 | case Relaxed
23 | case Normal
24 | case Furrowed
25 |
26 | func moreRelaxedBrow() -> EyeBrows {
27 | return EyeBrows(rawValue: rawValue - 1) ?? .Relaxed
28 | }
29 | func moreFurrowedBrow() -> EyeBrows {
30 | return EyeBrows(rawValue: rawValue + 1) ?? .Furrowed
31 | }
32 | }
33 |
34 | enum Mouth: Int {
35 | case Frown
36 | case Smirk
37 | case Neutral
38 | case Grin
39 | case Smile
40 |
41 | func sadderMouth() -> Mouth {
42 | return Mouth(rawValue: rawValue - 1) ?? .Frown
43 | }
44 | func happierMouth() -> Mouth {
45 | return Mouth(rawValue: rawValue + 1) ?? .Smile
46 | }
47 | }
48 |
49 | var eyes: Eyes
50 | var eyeBrows: EyeBrows
51 | var mouth: Mouth
52 | }
53 |
--------------------------------------------------------------------------------
/democode/FaceIt-L5/FaceIt/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/democode/FaceIt-L6/FaceIt.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/FaceIt-L6/FaceIt/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/democode/FaceIt-L6/FaceIt/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/democode/FaceIt-L6/FaceIt/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/FaceIt-L6/FaceIt/EmotionsViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EmotionsViewController.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class EmotionsViewController: UIViewController
12 | {
13 | private let emotionalFaces: Dictionary = [
14 | "angry" : FacialExpression(eyes: .Closed, eyeBrows: .Furrowed, mouth: .Frown),
15 | "happy" : FacialExpression(eyes: .Open, eyeBrows: .Normal, mouth: .Smile),
16 | "worried" : FacialExpression(eyes: .Open, eyeBrows: .Relaxed, mouth: .Smirk),
17 | "mischievious" : FacialExpression(eyes: .Open, eyeBrows: .Furrowed, mouth: .Grin)
18 | ]
19 |
20 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
21 | var destinationvc = segue.destinationViewController
22 | if let navcon = destinationvc as? UINavigationController {
23 | destinationvc = navcon.visibleViewController ?? destinationvc
24 | }
25 | if let facevc = destinationvc as? FaceViewController {
26 | if let identifier = segue.identifier {
27 | if let expression = emotionalFaces[identifier] {
28 | facevc.expression = expression
29 | if let sendingButton = sender as? UIButton {
30 | facevc.navigationItem.title = sendingButton.currentTitle
31 | }
32 | }
33 | }
34 | }
35 | }
36 |
37 | let instance = getEmotionsMVCinstanceCount()
38 | }
39 |
--------------------------------------------------------------------------------
/democode/FaceIt-L6/FaceIt/FaceViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FaceViewController: UIViewController
12 | {
13 | // MARK: Model
14 |
15 | var expression = FacialExpression(eyes: .Closed, eyeBrows: .Relaxed, mouth: .Smirk) {
16 | didSet {
17 | updateUI() // Model changed, so update the View
18 | }
19 | }
20 |
21 | // MARK: View
22 |
23 | @IBOutlet weak var faceView: FaceView! {
24 | didSet {
25 | faceView.addGestureRecognizer(UIPinchGestureRecognizer(
26 | target: faceView, action: #selector(FaceView.changeScale(_:))
27 | ))
28 |
29 | let happierSwipeGestureRecognizer = UISwipeGestureRecognizer(
30 | target: self, action: #selector(FaceViewController.increaseHappiness)
31 | )
32 | happierSwipeGestureRecognizer.direction = .Up
33 | faceView.addGestureRecognizer(happierSwipeGestureRecognizer)
34 |
35 | let sadderSwipeGestureRecognizer = UISwipeGestureRecognizer(
36 | target: self, action: #selector(FaceViewController.decreaseHappiness)
37 | )
38 | sadderSwipeGestureRecognizer.direction = .Down
39 | faceView.addGestureRecognizer(sadderSwipeGestureRecognizer)
40 |
41 | faceView.addGestureRecognizer(UIRotationGestureRecognizer(
42 | target: self, action: #selector(FaceViewController.changeBrows(_:))
43 | ))
44 |
45 | updateUI()
46 | }
47 | }
48 |
49 | private func updateUI() {
50 | if faceView != nil {
51 | switch expression.eyes {
52 | case .Open: faceView.eyesOpen = true
53 | case .Closed: faceView.eyesOpen = false
54 | case .Squinting: faceView.eyesOpen = false
55 | }
56 | faceView.mouthCurvature = mouthCurvatures[expression.mouth] ?? 0.0
57 | faceView.eyeBrowTilt = eyeBrowTilts[expression.eyeBrows] ?? 0.0
58 | }
59 | }
60 |
61 | private var mouthCurvatures = [FacialExpression.Mouth.Frown:-1.0,.Grin:0.5,.Smile:1.0,.Smirk:-0.5,.Neutral:0.0 ]
62 | private var eyeBrowTilts = [FacialExpression.EyeBrows.Relaxed:0.5,.Furrowed:-0.5,.Normal:0.0]
63 |
64 | // MARK: Gesture Handlers
65 |
66 | func increaseHappiness() {
67 | expression.mouth = expression.mouth.happierMouth()
68 | }
69 |
70 | func decreaseHappiness() {
71 | expression.mouth = expression.mouth.sadderMouth()
72 | }
73 |
74 | @IBAction func toggleEyes(recognizer: UITapGestureRecognizer) {
75 | if recognizer.state == .Ended {
76 | switch expression.eyes {
77 | case .Open: expression.eyes = .Closed
78 | case .Closed: expression.eyes = .Open
79 | case .Squinting: break // we don't know how to toggle "Squinting"
80 | }
81 | }
82 | }
83 |
84 | func changeBrows(recognizer: UIRotationGestureRecognizer) {
85 | switch recognizer.state {
86 | case .Changed,.Ended:
87 | if recognizer.rotation > CGFloat(M_PI/4) {
88 | expression.eyeBrows = expression.eyeBrows.moreRelaxedBrow()
89 | recognizer.rotation = 0.0
90 | } else if recognizer.rotation < -CGFloat(M_PI/4) {
91 | expression.eyeBrows = expression.eyeBrows.moreFurrowedBrow()
92 | recognizer.rotation = 0.0
93 | }
94 | default:
95 | break
96 | }
97 | }
98 |
99 | let instance = getFaceMVCinstanceCount()
100 | }
101 |
--------------------------------------------------------------------------------
/democode/FaceIt-L6/FaceIt/FacialExpression.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FacialExpression.swift
3 | // FaceIt
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2015-16 Stanford University. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // UI-independent representation of a facial expression
12 |
13 | struct FacialExpression
14 | {
15 | enum Eyes: Int {
16 | case Open
17 | case Closed
18 | case Squinting
19 | }
20 |
21 | enum EyeBrows: Int {
22 | case Relaxed
23 | case Normal
24 | case Furrowed
25 |
26 | func moreRelaxedBrow() -> EyeBrows {
27 | return EyeBrows(rawValue: rawValue - 1) ?? .Relaxed
28 | }
29 | func moreFurrowedBrow() -> EyeBrows {
30 | return EyeBrows(rawValue: rawValue + 1) ?? .Furrowed
31 | }
32 | }
33 |
34 | enum Mouth: Int {
35 | case Frown
36 | case Smirk
37 | case Neutral
38 | case Grin
39 | case Smile
40 |
41 | func sadderMouth() -> Mouth {
42 | return Mouth(rawValue: rawValue - 1) ?? .Frown
43 | }
44 | func happierMouth() -> Mouth {
45 | return Mouth(rawValue: rawValue + 1) ?? .Smile
46 | }
47 | }
48 |
49 | var eyes: Eyes
50 | var eyeBrows: EyeBrows
51 | var mouth: Mouth
52 | }
53 |
--------------------------------------------------------------------------------
/democode/FaceIt-L6/FaceIt/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/democode/Pollster-L16/Pollster.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/Pollster-L16/Pollster/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Pollster
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CloudKit
11 |
12 | @UIApplicationMain
13 | class AppDelegate: UIResponder, UIApplicationDelegate {
14 |
15 | var window: UIWindow?
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | let settings = UIUserNotificationSettings(forTypes: [.Alert,.Badge,.Sound], categories: nil)
20 | application.registerUserNotificationSettings(settings)
21 | application.registerForRemoteNotifications()
22 | return true
23 | }
24 |
25 | func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
26 | let ckqn = CKQueryNotification(fromRemoteNotificationDictionary: userInfo as! [String:NSObject])
27 | let notification = NSNotification(
28 | name: CloudKitNotifications.NotificationReceived,
29 | object: self,
30 | userInfo: [CloudKitNotifications.NotificationKey:ckqn]
31 | )
32 | NSNotificationCenter.defaultCenter().postNotification(notification)
33 | }
34 |
35 | func applicationWillResignActive(application: UIApplication) {
36 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
37 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
38 | }
39 |
40 | func applicationDidEnterBackground(application: UIApplication) {
41 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
42 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
43 | }
44 |
45 | func applicationWillEnterForeground(application: UIApplication) {
46 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
47 | }
48 |
49 | func applicationDidBecomeActive(application: UIApplication) {
50 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
51 | }
52 |
53 | func applicationWillTerminate(application: UIApplication) {
54 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
55 | }
56 |
57 |
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/democode/Pollster-L16/Pollster/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/democode/Pollster-L16/Pollster/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/Pollster-L16/Pollster/CloudKitExtensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CloudKitExtensions.swift
3 | // Pollster
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import CloudKit
10 |
11 | // these are read-only
12 | // one could make read-write versions of them just as easily
13 |
14 | extension CKRecord {
15 | var question: String {
16 | return self[Cloud.Attribute.Question] as? String ?? ""
17 | }
18 | var answers: [String] {
19 | return self[Cloud.Attribute.Answers] as? [String] ?? []
20 | }
21 | }
22 |
23 | // Constants
24 |
25 | struct CloudKitNotifications {
26 | static let NotificationReceived = "iCloudRemoteNotificationReceived"
27 | static let NotificationKey = "Notification"
28 | }
29 |
30 | struct Cloud {
31 | struct Entity {
32 | static let QandA = "QandA"
33 | static let Response = "Response"
34 | }
35 | struct Attribute {
36 | static let Question = "question"
37 | static let Answers = "answers"
38 | static let ChosenAnswer = "chosenAnswer"
39 | static let QandA = "qanda"
40 | }
41 | }
42 |
43 | // probably in a real application
44 | // you'd have an Entity in the database for users
45 | // and so you wouldn't use this way of determining whether
46 | // the record was authored by the currently-logged-in iCloud user
47 |
48 | extension CKRecord {
49 | var wasCreatedByThisUser: Bool {
50 | // is this really the right way to do this?
51 | // seems like this Bool property should be built in to CKRecord
52 | return (creatorUserRecordID == nil) || (creatorUserRecordID?.recordName == "__defaultOwner__")
53 | }
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/democode/Pollster-L16/Pollster/CloudQandATableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CloudQandATableViewController.swift
3 | // Pollster
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CloudKit
11 |
12 | class CloudQandATableViewController: QandATableViewController
13 | {
14 | // MARK: Model
15 |
16 | var ckQandARecord: CKRecord {
17 | get {
18 | if _ckQandARecord == nil {
19 | _ckQandARecord = CKRecord(recordType: Cloud.Entity.QandA)
20 | }
21 | return _ckQandARecord!
22 | }
23 | set {
24 | _ckQandARecord = newValue
25 | }
26 | }
27 |
28 | // MARK: UITextViewDelegate
29 |
30 | override func textViewDidEndEditing(textView: UITextView) {
31 | super.textViewDidEndEditing(textView)
32 | iCloudUpdate()
33 | }
34 |
35 | // MARK: Private Implementation
36 |
37 | private var _ckQandARecord: CKRecord? {
38 | didSet {
39 | let question = ckQandARecord[Cloud.Attribute.Question] as? String ?? ""
40 | let answers = ckQandARecord[Cloud.Attribute.Answers] as? [String] ?? []
41 | qanda = QandA(question: question, answers: answers)
42 |
43 | asking = ckQandARecord.wasCreatedByThisUser
44 | }
45 | }
46 |
47 | private let database = CKContainer.defaultContainer().publicCloudDatabase
48 |
49 | @objc private func iCloudUpdate() {
50 | if !qanda.question.isEmpty && !qanda.answers.isEmpty {
51 | ckQandARecord[Cloud.Attribute.Question] = qanda.question
52 | ckQandARecord[Cloud.Attribute.Answers] = qanda.answers
53 | iCloudSaveRecord(ckQandARecord)
54 | }
55 | }
56 |
57 | private func iCloudSaveRecord(recordToSave: CKRecord) {
58 | database.saveRecord(recordToSave) { (savedRecord, error) in
59 | if error?.code == CKErrorCode.ServerRecordChanged.rawValue {
60 | // optimistic locking failed, ignore
61 | } else if error != nil {
62 | self.retryAfterError(error, withSelector: #selector(self.iCloudUpdate))
63 | }
64 | }
65 | }
66 |
67 | private func retryAfterError(error: NSError?, withSelector selector: Selector) {
68 | if let retryInterval = error?.userInfo[CKErrorRetryAfterKey] as? NSTimeInterval {
69 | dispatch_async(dispatch_get_main_queue()) {
70 | NSTimer.scheduledTimerWithTimeInterval(
71 | retryInterval,
72 | target: self, selector: selector,
73 | userInfo: nil, repeats: false
74 | )
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/democode/Pollster-L16/Pollster/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/democode/Pollster-L16/Pollster/Pollster.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.developer.icloud-container-identifiers
6 |
7 | iCloud.$(CFBundleIdentifier)
8 |
9 | com.apple.developer.icloud-services
10 |
11 | CloudKit
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/democode/Pollster-L16/Pollster/QandAAccessoryTableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QandAAccessoryDoneTableViewController.swift
3 | // Pollster
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // Adds accessoryValues for the cells
12 |
13 | class QandAAccessoryTableViewController: QandATableViewController
14 | {
15 | // MARK: Public API
16 |
17 | // key is content found in a cell
18 | // value is what to put in the accessory label for that cell
19 | // note: if two cells have the same content, they'll both get the same accessory value
20 | // (which may or may not be what you want, but there it is)
21 |
22 | var accessoryValues = [String:CustomStringConvertible]() {
23 | didSet {
24 | for content in data?[Section.Answers] ?? [] {
25 | accessoryLabelForContent(content)?.text = "\(accessoryValues[content] ?? "")"
26 | }
27 | }
28 | }
29 |
30 | // MARK: - Private Implementation
31 |
32 | private func accessoryLabelForContent(content: String) -> UILabel? {
33 | for cell in tableView.visibleCells {
34 | for subview in cell.contentView.subviews {
35 | if let textView = subview as? UITextView where textView.text == content {
36 | for subview in textView.subviews {
37 | if let label = subview as? UILabel {
38 | return label
39 | }
40 | }
41 | }
42 | }
43 | }
44 | return nil
45 | }
46 |
47 | override func createTextViewForIndexPath(indexPath: NSIndexPath?) -> UITextView {
48 | let textView = super.createTextViewForIndexPath(indexPath)
49 | createAccessoryLabel(inTextView: textView)
50 | return textView
51 | }
52 |
53 | private func createAccessoryLabel(inTextView textView: UITextView) {
54 | let label = UILabel()
55 | label.textAlignment = .Right
56 | label.text = "100"
57 | label.sizeToFit()
58 | let width = label.bounds.size.width
59 | label.frame = CGRect(x: textView.bounds.maxX - width, y: 0, width: width, height: textView.bounds.size.height)
60 | label.text = ""
61 | label.autoresizingMask = [.FlexibleHeight,.FlexibleLeftMargin]
62 | textView.addSubview(label)
63 | }
64 |
65 | // MARK: UITableViewDataSource
66 |
67 | override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
68 | let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)
69 | if asking && indexPath.section == Section.Answers {
70 | if let answerInRow = data?[indexPath.section][indexPath.row] {
71 | accessoryLabelForContent(answerInRow)?.text = "\(accessoryValues[answerInRow] ?? "")"
72 | }
73 | }
74 | return cell
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/democode/README.md:
--------------------------------------------------------------------------------
1 | ### Demo Code
2 | This is the demo code as entered per lecture.
3 |
4 | Project | Xcode Project
5 | ------------- | -------------
6 | 1. | [Lecture 4: Drawing and Views](FaceIt-L4)
7 | 2. | [Lecture 5: Gestures](FaceIt-L5)
8 | 3. | [Lecture 6: Multiple MVCs](FaceIt-L6)
9 | 4. | [Lecture 7: Delegation & Scroll View](Cassini-L7)
10 | 5. | [Lecture 8: Multithreading](Cassini-L8)
11 | 6. | [Lecture 9: Table View](Smashtag-L9)
12 | 7. | [Lecture 11: Core Data](Smashtag-L11)
13 | 8. | [Lecture 13: NSTimer & UIView Animation](FaceIt-L13)
14 | 9. | [Lecture 14: Animation](DropIt-L14)
15 | 10. | [Lecture 16: CloudKit](Pollster-L16)
16 | 11. | [Lectures 17 & 18: MapKit and Segues](Trax-L18)
17 |
18 | ## Support or Contact
19 | Visit [ddApps.co](http://ddapps.co) to see more.
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/CoreDataTableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataTableViewController.swift
3 | //
4 | // Created by CS193p Instructor.
5 | // Copyright © 2015-16 Stanford University. All rights reserved.
6 | //
7 |
8 | import UIKit
9 | import CoreData
10 |
11 | class CoreDataTableViewController: UITableViewController, NSFetchedResultsControllerDelegate
12 | {
13 | var fetchedResultsController: NSFetchedResultsController? {
14 | didSet {
15 | do {
16 | if let frc = fetchedResultsController {
17 | frc.delegate = self
18 | try frc.performFetch()
19 | }
20 | tableView.reloadData()
21 | } catch let error {
22 | print("NSFetchedResultsController.performFetch() failed: \(error)")
23 | }
24 | }
25 | }
26 |
27 | // MARK: UITableViewDataSource
28 |
29 | override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
30 | return fetchedResultsController?.sections?.count ?? 1
31 | }
32 |
33 | override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
34 | if let sections = fetchedResultsController?.sections where sections.count > 0 {
35 | return sections[section].numberOfObjects
36 | } else {
37 | return 0
38 | }
39 | }
40 |
41 | override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
42 | if let sections = fetchedResultsController?.sections where sections.count > 0 {
43 | return sections[section].name
44 | } else {
45 | return nil
46 | }
47 | }
48 |
49 | override func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
50 | return fetchedResultsController?.sectionIndexTitles
51 | }
52 |
53 | override func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
54 | return fetchedResultsController?.sectionForSectionIndexTitle(title, atIndex: index) ?? 0
55 | }
56 |
57 | // MARK: NSFetchedResultsControllerDelegate
58 |
59 | func controllerWillChangeContent(controller: NSFetchedResultsController) {
60 | tableView.beginUpdates()
61 | }
62 |
63 | func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
64 | switch type {
65 | case .Insert: tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
66 | case .Delete: tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
67 | default: break
68 | }
69 | }
70 |
71 | func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
72 | switch type {
73 | case .Insert:
74 | tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
75 | case .Delete:
76 | tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
77 | case .Update:
78 | tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
79 | case .Move:
80 | tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
81 | tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
82 | }
83 | }
84 |
85 | func controllerDidChangeContent(controller: NSFetchedResultsController) {
86 | tableView.endUpdates()
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | NSAppTransportSecurity
26 |
27 | NSAllowsArbitraryLoads
28 |
29 |
30 | UILaunchStoryboardName
31 | LaunchScreen
32 | UIMainStoryboardFile
33 | Main
34 | UIRequiredDeviceCapabilities
35 |
36 | armv7
37 |
38 | UISupportedInterfaceOrientations
39 |
40 | UIInterfaceOrientationPortrait
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/Model.xcdatamodeld/Model.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/Tweet+CoreDataProperties.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Tweet+CoreDataProperties.swift
3 | // Smashtag
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu
9 | // to delete and recreate this implementation file for your updated model.
10 | //
11 |
12 | import Foundation
13 | import CoreData
14 |
15 | extension Tweet {
16 |
17 | @NSManaged var text: String?
18 | @NSManaged var unique: String?
19 | @NSManaged var posted: NSDate?
20 | @NSManaged var tweeter: TwitterUser?
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/Tweet.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Tweet.swift
3 | // Smashtag
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 | import Twitter
12 |
13 | class Tweet: NSManagedObject
14 | {
15 | // a class method which
16 | // returns a Tweet from the database if Twitter.Tweet has already been put in
17 | // or returns a newly-added-to-the-database Tweet if not
18 |
19 | class func tweetWithTwitterInfo(twitterInfo: Twitter.Tweet, inManagedObjectContext context: NSManagedObjectContext) -> Tweet?
20 | {
21 | let request = NSFetchRequest(entityName: "Tweet")
22 | request.predicate = NSPredicate(format: "unique = %@", twitterInfo.id)
23 |
24 | if let tweet = (try? context.executeFetchRequest(request))?.first as? Tweet {
25 | // found this tweet in the database, return it ...
26 | return tweet
27 | } else if let tweet = NSEntityDescription.insertNewObjectForEntityForName("Tweet", inManagedObjectContext: context) as? Tweet {
28 | // created a new tweet in the database
29 | // load it up with information from the Twitter.Tweet ...
30 | tweet.unique = twitterInfo.id
31 | tweet.text = twitterInfo.text
32 | tweet.posted = twitterInfo.created
33 | tweet.tweeter = TwitterUser.twitterUserWithTwitterInfo(twitterInfo.user, inManagedObjectContext: context)
34 | return tweet
35 | }
36 |
37 | return nil
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/TweetTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TweetTableViewCell.swift
3 | // Smashtag
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Twitter
11 |
12 | class TweetTableViewCell: UITableViewCell
13 | {
14 | @IBOutlet weak var tweetScreenNameLabel: UILabel!
15 | @IBOutlet weak var tweetTextLabel: UILabel!
16 | @IBOutlet weak var tweetProfileImageView: UIImageView!
17 | @IBOutlet weak var tweetCreatedLabel: UILabel!
18 |
19 | var tweet: Twitter.Tweet? {
20 | didSet {
21 | updateUI()
22 | }
23 | }
24 |
25 | private func updateUI()
26 | {
27 | // reset any existing tweet information
28 | tweetTextLabel?.attributedText = nil
29 | tweetScreenNameLabel?.text = nil
30 | tweetProfileImageView?.image = nil
31 | tweetCreatedLabel?.text = nil
32 |
33 | // load new information from our tweet (if any)
34 | if let tweet = self.tweet
35 | {
36 | tweetTextLabel?.text = tweet.text
37 | if tweetTextLabel?.text != nil {
38 | for _ in tweet.media {
39 | tweetTextLabel.text! += " 📷"
40 | }
41 | }
42 |
43 | tweetScreenNameLabel?.text = "\(tweet.user)" // tweet.user.description
44 |
45 | if let profileImageURL = tweet.user.profileImageURL {
46 | if let imageData = NSData(contentsOfURL: profileImageURL) { // blocks main thread!
47 | tweetProfileImageView?.image = UIImage(data: imageData)
48 | }
49 | }
50 |
51 | let formatter = NSDateFormatter()
52 | if NSDate().timeIntervalSinceDate(tweet.created) > 24*60*60 {
53 | formatter.dateStyle = NSDateFormatterStyle.ShortStyle
54 | } else {
55 | formatter.timeStyle = NSDateFormatterStyle.ShortStyle
56 | }
57 | tweetCreatedLabel?.text = formatter.stringFromDate(tweet.created)
58 | }
59 |
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/TweetersTableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TweetersTableViewController.swift
3 | // Smashtag
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoreData
11 |
12 | // uses CoreDataTableViewController as its superclass
13 | // so all we need to do is set the fetchedResultsController var
14 | // and implement tableView(cellForRowAtIndexPath:)
15 |
16 | class TweetersTableViewController: CoreDataTableViewController
17 | {
18 | var mention: String? { didSet { updateUI() } }
19 | var managedObjectContext: NSManagedObjectContext? { didSet { updateUI() } }
20 |
21 | private func updateUI() {
22 | if let context = managedObjectContext where mention?.characters.count > 0 {
23 | let request = NSFetchRequest(entityName: "TwitterUser")
24 | request.predicate = NSPredicate(format: "any tweets.text contains[c] %@ and !screenName beginswith[c] %@", mention!, "darkside")
25 | request.sortDescriptors = [NSSortDescriptor(
26 | key: "screenName",
27 | ascending: true,
28 | selector: #selector(NSString.localizedCaseInsensitiveCompare(_:))
29 | )]
30 | fetchedResultsController = NSFetchedResultsController(
31 | fetchRequest: request,
32 | managedObjectContext: context,
33 | sectionNameKeyPath: nil,
34 | cacheName: nil
35 | )
36 | } else {
37 | fetchedResultsController = nil
38 | }
39 | }
40 |
41 | // this is the only UITableViewDataSource method we have to implement
42 | // if we use a CoreDataTableViewController
43 | // the most important call is fetchedResultsController?.objectAtIndexPath(indexPath)
44 | // (that's how we get the object that is in this row so we can load the cell up)
45 |
46 | override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
47 | let cell = tableView.dequeueReusableCellWithIdentifier("TwitterUserCell", forIndexPath: indexPath)
48 |
49 | if let twitterUser = fetchedResultsController?.objectAtIndexPath(indexPath) as? TwitterUser {
50 | var screenName: String?
51 | twitterUser.managedObjectContext?.performBlockAndWait {
52 | // it's easy to forget to do this on the proper queue
53 | screenName = twitterUser.screenName
54 | // we're not assuming the context is a main queue context
55 | // so we'll grab the screenName and return to the main queue
56 | // to do the cell.textLabel?.text setting
57 | }
58 | cell.textLabel?.text = screenName
59 | if let count = tweetCountWithMentionByTwitterUser(twitterUser) {
60 | cell.detailTextLabel?.text = (count == 1) ? "1 tweet" : "\(count) tweets"
61 | } else {
62 | cell.detailTextLabel?.text = ""
63 | }
64 | }
65 |
66 | return cell
67 | }
68 |
69 | // private func which figures out how many tweets
70 | // were tweeted by the given user that contain our mention
71 |
72 | private func tweetCountWithMentionByTwitterUser(user: TwitterUser) -> Int?
73 | {
74 | var count: Int?
75 | user.managedObjectContext?.performBlockAndWait {
76 | let request = NSFetchRequest(entityName: "Tweet")
77 | request.predicate = NSPredicate(format: "text contains[c] %@ and tweeter = %@", self.mention!, user)
78 | count = user.managedObjectContext?.countForFetchRequest(request, error: nil)
79 | }
80 | return count
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/TwitterUser+CoreDataProperties.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TwitterUser+CoreDataProperties.swift
3 | // Smashtag
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu
9 | // to delete and recreate this implementation file for your updated model.
10 | //
11 |
12 | import Foundation
13 | import CoreData
14 |
15 | extension TwitterUser {
16 |
17 | @NSManaged var screenName: String?
18 | @NSManaged var name: String?
19 | @NSManaged var tweets: NSSet?
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/democode/Smashtag-L11/Smashtag/TwitterUser.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TwitterUser.swift
3 | // Smashtag
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 | import Twitter
12 |
13 | class TwitterUser: NSManagedObject
14 | {
15 | // a class method which
16 | // returns a TwitterUser from the database if Twitter.User has already been put in
17 | // or returns a newly-added-to-the-database TwitterUser if not
18 |
19 | class func twitterUserWithTwitterInfo(twitterInfo: Twitter.User, inManagedObjectContext context: NSManagedObjectContext) -> TwitterUser?
20 | {
21 | let request = NSFetchRequest(entityName: "TwitterUser")
22 | request.predicate = NSPredicate(format: "screenName = %@", twitterInfo.screenName)
23 | if let twitterUser = (try? context.executeFetchRequest(request))?.first as? TwitterUser {
24 | return twitterUser
25 | } else if let twitterUser = NSEntityDescription.insertNewObjectForEntityForName("TwitterUser", inManagedObjectContext: context) as? TwitterUser {
26 | twitterUser.screenName = twitterInfo.screenName
27 | twitterUser.name = twitterInfo.name
28 | return twitterUser
29 | }
30 | return nil
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Smashtag/Smashtag.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Smashtag/Smashtag/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Smashtag
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Smashtag/Smashtag/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Smashtag/Smashtag/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Smashtag/Smashtag/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | NSAppTransportSecurity
26 |
27 | NSAllowsArbitraryLoads
28 |
29 |
30 | UILaunchStoryboardName
31 | LaunchScreen
32 | UIMainStoryboardFile
33 | Main
34 | UIRequiredDeviceCapabilities
35 |
36 | armv7
37 |
38 | UISupportedInterfaceOrientations
39 |
40 | UIInterfaceOrientationPortrait
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Smashtag/Smashtag/TweetTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TweetTableViewCell.swift
3 | // Smashtag
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Twitter
11 |
12 | class TweetTableViewCell: UITableViewCell
13 | {
14 | @IBOutlet weak var tweetScreenNameLabel: UILabel!
15 | @IBOutlet weak var tweetTextLabel: UILabel!
16 | @IBOutlet weak var tweetProfileImageView: UIImageView!
17 | @IBOutlet weak var tweetCreatedLabel: UILabel!
18 |
19 | var tweet: Twitter.Tweet? {
20 | didSet {
21 | updateUI()
22 | }
23 | }
24 |
25 | private func updateUI()
26 | {
27 | // reset any existing tweet information
28 | tweetTextLabel?.attributedText = nil
29 | tweetScreenNameLabel?.text = nil
30 | tweetProfileImageView?.image = nil
31 | tweetCreatedLabel?.text = nil
32 |
33 | // load new information from our tweet (if any)
34 | if let tweet = self.tweet
35 | {
36 | tweetTextLabel?.text = tweet.text
37 | if tweetTextLabel?.text != nil {
38 | for _ in tweet.media {
39 | tweetTextLabel.text! += " 📷"
40 | }
41 | }
42 |
43 | tweetScreenNameLabel?.text = "\(tweet.user)" // tweet.user.description
44 |
45 | if let profileImageURL = tweet.user.profileImageURL {
46 | if let imageData = NSData(contentsOfURL: profileImageURL) { // blocks main thread!
47 | tweetProfileImageView?.image = UIImage(data: imageData)
48 | }
49 | }
50 |
51 | let formatter = NSDateFormatter()
52 | if NSDate().timeIntervalSinceDate(tweet.created) > 24*60*60 {
53 | formatter.dateStyle = NSDateFormatterStyle.ShortStyle
54 | } else {
55 | formatter.timeStyle = NSDateFormatterStyle.ShortStyle
56 | }
57 | tweetCreatedLabel?.text = formatter.stringFromDate(tweet.created)
58 | }
59 |
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Smashtag/Smashtag/TweetTableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TweetTableViewController.swift
3 | // Smashtag
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Twitter
11 |
12 | class TweetTableViewController: UITableViewController, UITextFieldDelegate
13 | {
14 | // MARK: Model
15 |
16 | var tweets = [Array]() {
17 | didSet {
18 | tableView.reloadData()
19 | }
20 | }
21 |
22 | var searchText: String? {
23 | didSet {
24 | tweets.removeAll()
25 | lastTwitterRequest = nil
26 | searchForTweets()
27 | title = searchText
28 | }
29 | }
30 |
31 | // MARK: Fetching Tweets
32 |
33 | private var twitterRequest: Twitter.Request? {
34 | if lastTwitterRequest == nil {
35 | if let query = searchText where !query.isEmpty {
36 | return Twitter.Request(search: query + " -filter:retweets", count: 100)
37 | }
38 | }
39 | return lastTwitterRequest?.requestForNewer
40 | }
41 |
42 | private var lastTwitterRequest: Twitter.Request?
43 |
44 | private func searchForTweets()
45 | {
46 | if let request = twitterRequest {
47 | lastTwitterRequest = request
48 | request.fetchTweets { [weak weakSelf = self] newTweets in
49 | dispatch_async(dispatch_get_main_queue()) {
50 | if request == weakSelf?.lastTwitterRequest {
51 | if !newTweets.isEmpty {
52 | weakSelf?.tweets.insert(newTweets, atIndex: 0)
53 | }
54 | }
55 | weakSelf?.refreshControl?.endRefreshing()
56 | }
57 | }
58 | } else {
59 | self.refreshControl?.endRefreshing()
60 | }
61 | }
62 |
63 | @IBAction func refresh(sender: UIRefreshControl) {
64 | searchForTweets()
65 | }
66 |
67 | // MARK: UITableViewDataSource
68 |
69 | override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
70 | return "\(tweets.count - section)"
71 | }
72 |
73 | override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
74 | return tweets.count
75 | }
76 |
77 | override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
78 | return tweets[section].count
79 | }
80 |
81 | override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
82 | let cell = tableView.dequeueReusableCellWithIdentifier(Storyboard.TweetCellIdentifier, forIndexPath: indexPath)
83 |
84 | let tweet = tweets[indexPath.section][indexPath.row]
85 | if let tweetCell = cell as? TweetTableViewCell {
86 | tweetCell.tweet = tweet
87 | }
88 |
89 | return cell
90 | }
91 |
92 | // MARK: Constants
93 |
94 | private struct Storyboard {
95 | static let TweetCellIdentifier = "Tweet"
96 | }
97 |
98 | // MARK: Outlets
99 |
100 | @IBOutlet weak var searchTextField: UITextField! {
101 | didSet {
102 | searchTextField.delegate = self
103 | searchTextField.text = searchText
104 | }
105 | }
106 |
107 | // MARK: UITextFieldDelegate
108 |
109 | func textFieldShouldReturn(textField: UITextField) -> Bool {
110 | textField.resignFirstResponder()
111 | searchText = textField.text
112 | return true
113 | }
114 |
115 | // MARK: View Controller Lifecycle
116 |
117 | override func viewDidLoad() {
118 | super.viewDidLoad()
119 | tableView.estimatedRowHeight = tableView.rowHeight
120 | tableView.rowHeight = UITableViewAutomaticDimension
121 | }
122 |
123 | /*
124 | // MARK: - Navigation
125 |
126 | // In a storyboard-based application, you will often want to do a little preparation before navigation
127 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
128 | // Get the new view controller using segue.destinationViewController.
129 | // Pass the selected object to the new view controller.
130 | }
131 | */
132 | }
133 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Twitter/Twitter.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Twitter/Twitter/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en_US
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Twitter/Twitter/MediaItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MediaItem.swift
3 | // Twitter
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2015 Stanford University. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // holds the network url and aspectRatio of an image attached to a Tweet
12 | // created automatically when a Tweet object is created
13 |
14 | public class MediaItem: NSObject
15 | {
16 | public let url: NSURL
17 | public let aspectRatio: Double
18 |
19 | public override var description: String { return "\(url.absoluteString) (aspect ratio = \(aspectRatio))" }
20 |
21 | // MARK: - Internal Implementation
22 |
23 | init?(data: NSDictionary?) {
24 | guard
25 | let height = data?.valueForKeyPath(TwitterKey.Height) as? Double where height > 0,
26 | let width = data?.valueForKeyPath(TwitterKey.Width) as? Double where width > 0,
27 | let urlString = data?.valueForKeyPath(TwitterKey.MediaURL) as? String,
28 | let url = NSURL(string: urlString)
29 | else {
30 | return nil
31 | }
32 | self.url = url
33 | self.aspectRatio = width/height
34 | }
35 |
36 | struct TwitterKey {
37 | static let MediaURL = "media_url_https"
38 | static let Width = "sizes.small.w"
39 | static let Height = "sizes.small.h"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Twitter/Twitter/Twitter.h:
--------------------------------------------------------------------------------
1 | //
2 | // Twitter.h
3 | // Twitter
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2015 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for Twitter.
12 | FOUNDATION_EXPORT double TwitterVersionNumber;
13 |
14 | //! Project version string for Twitter.
15 | FOUNDATION_EXPORT const unsigned char TwitterVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
--------------------------------------------------------------------------------
/democode/Smashtag-L9/Twitter/Twitter/User.swift:
--------------------------------------------------------------------------------
1 | //
2 | // User.swift
3 | // Twitter
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2015 Stanford University. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // container to hold data about a Twitter user
12 |
13 | public class User: NSObject
14 | {
15 | public let screenName: String
16 | public let name: String
17 | public let id: String
18 | public let verified: Bool
19 | public let profileImageURL: NSURL?
20 |
21 | public override var description: String { return "@\(screenName) (\(name))\(verified ? " ✅" : "")" }
22 |
23 | // MARK: - Internal Implementation
24 |
25 | init?(data: NSDictionary?) {
26 | guard
27 | let screenName = data?.valueForKeyPath(TwitterKey.ScreenName) as? String,
28 | let name = data?.valueForKeyPath(TwitterKey.Name) as? String,
29 | let id = data?.valueForKeyPath(TwitterKey.ID) as? String
30 | else {
31 | return nil
32 | }
33 |
34 | self.screenName = screenName
35 | self.name = name
36 | self.id = id
37 |
38 | self.verified = data?.valueForKeyPath(TwitterKey.Verified)?.boolValue ?? false
39 | let urlString = data?.valueForKeyPath(TwitterKey.ProfileImageURL) as? String ?? ""
40 | self.profileImageURL = (urlString.characters.count > 0) ? NSURL(string: urlString) : nil
41 | }
42 |
43 | var asPropertyList: AnyObject {
44 | return [
45 | TwitterKey.Name:name,
46 | TwitterKey.ScreenName:screenName,
47 | TwitterKey.ID:id,
48 | TwitterKey.Verified:verified ? "YES" : "NO",
49 | TwitterKey.ProfileImageURL:profileImageURL?.absoluteString ?? ""
50 | ]
51 | }
52 |
53 | struct TwitterKey {
54 | static let Name = "name"
55 | static let ScreenName = "screen_name"
56 | static let ID = "id_str"
57 | static let Verified = "verified"
58 | static let ProfileImageURL = "profile_image_url"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/democode/Trax-L18/Trax.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/democode/Trax-L18/Trax/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Trax
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/democode/Trax-L18/Trax/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/democode/Trax-L18/Trax/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/democode/Trax-L18/Trax/EditWaypointViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EditWaypointViewController.swift
3 | // Trax
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class EditWaypointViewController: UIViewController, UITextFieldDelegate
12 | {
13 | // MARK: Public API
14 |
15 | var waypointToEdit: EditableWaypoint? { didSet { updateUI() } }
16 |
17 | // MARK: View Controller Lifecycle
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | updateUI()
22 | nameTextField.becomeFirstResponder()
23 | }
24 |
25 | override func viewDidAppear(animated: Bool) {
26 | super.viewDidAppear(animated)
27 | listenToTextFields()
28 | }
29 |
30 | override func viewWillDisappear(animated: Bool) {
31 | super.viewWillDisappear(animated)
32 | stopListeningToTextFields()
33 | }
34 |
35 | override func viewWillLayoutSubviews() {
36 | super.viewWillLayoutSubviews()
37 | preferredContentSize = view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
38 | }
39 |
40 | // MARK: Private Implementation
41 |
42 | @IBOutlet weak var nameTextField: UITextField! { didSet { nameTextField.delegate = self } }
43 | @IBOutlet weak var infoTextField: UITextField! { didSet { infoTextField.delegate = self } }
44 |
45 | private func updateUI() {
46 | nameTextField?.text = waypointToEdit?.name
47 | infoTextField?.text = waypointToEdit?.info
48 | }
49 |
50 | private var ntfObserver: NSObjectProtocol?
51 | private var itfObserver: NSObjectProtocol?
52 |
53 | private func listenToTextFields()
54 | {
55 | let center = NSNotificationCenter.defaultCenter()
56 | let queue = NSOperationQueue.mainQueue()
57 |
58 | ntfObserver = center.addObserverForName(
59 | UITextFieldTextDidChangeNotification,
60 | object: nameTextField,
61 | queue: queue)
62 | { notification in
63 | if let waypoint = self.waypointToEdit {
64 | waypoint.name = self.nameTextField.text
65 | }
66 | }
67 | itfObserver = center.addObserverForName(
68 | UITextFieldTextDidChangeNotification,
69 | object: infoTextField,
70 | queue: queue)
71 | { notification in
72 | if let waypoint = self.waypointToEdit {
73 | waypoint.info = self.infoTextField.text
74 | }
75 | }
76 | }
77 |
78 | private func stopListeningToTextFields() {
79 | if let observer = ntfObserver {
80 | NSNotificationCenter.defaultCenter().removeObserver(observer)
81 | }
82 | if let observer = itfObserver {
83 | NSNotificationCenter.defaultCenter().removeObserver(observer)
84 | }
85 | }
86 |
87 | // MARK: UITextFieldDelegate
88 |
89 | func textFieldShouldReturn(textField: UITextField) -> Bool {
90 | textField.resignFirstResponder()
91 | return true
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/democode/Trax-L18/Trax/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | NSAppTransportSecurity
40 |
41 | NSAllowsArbitraryLoads
42 |
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/democode/Trax-L18/Trax/MKGPX.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MKGPX.swift
3 | // Trax
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright © 2016 Stanford University. All rights reserved.
7 | //
8 | // Enhancements to GPX.Waypoint to support MKMapView
9 |
10 | import MapKit
11 |
12 | // EditableWaypoints are draggable
13 | // so their coordinate needs to be settable
14 |
15 | class EditableWaypoint : GPX.Waypoint
16 | {
17 | override var coordinate: CLLocationCoordinate2D {
18 | get {
19 | return super.coordinate
20 | }
21 | set {
22 | latitude = newValue.latitude
23 | longitude = newValue.longitude
24 | }
25 | }
26 | }
27 |
28 | extension GPX.Waypoint : MKAnnotation
29 | {
30 | var coordinate: CLLocationCoordinate2D {
31 | return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
32 | }
33 |
34 | var title: String? { return name }
35 |
36 | var subtitle: String? { return info }
37 |
38 | var thumbnailURL: NSURL? {
39 | return getImageURLofType("thumbnail")
40 | }
41 |
42 | var imageURL: NSURL? {
43 | return getImageURLofType("large")
44 | }
45 |
46 | // look in the hyperlink information from the GPX file
47 | // try to find a url with a given type
48 |
49 | private func getImageURLofType(type: String?) -> NSURL? {
50 | for link in links {
51 | if link.type == type {
52 | return link.url
53 | }
54 | }
55 | return nil
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/problemsets/Programming_Project_1_Calculator.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/Programming_Project_1_Calculator.pdf
--------------------------------------------------------------------------------
/problemsets/Programming_Project_2_Calculator_Brain.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/Programming_Project_2_Calculator_Brain.pdf
--------------------------------------------------------------------------------
/problemsets/Programming_Project_3_Graphic_Calculator.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/Programming_Project_3_Graphic_Calculator.pdf
--------------------------------------------------------------------------------
/problemsets/Programming_Project_4_Smashtag_Mentions.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/Programming_Project_4_Smashtag_Mentions.pdf
--------------------------------------------------------------------------------
/problemsets/Programming_Project_5_Smashtag_Ment.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/Programming_Project_5_Smashtag_Ment.pdf
--------------------------------------------------------------------------------
/problemsets/Programming_Project_6_Animation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/Programming_Project_6_Animation.pdf
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/AppIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/AppIcon.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/AppIcon.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/AppIcon.xcf
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-40.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-40@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-40@3x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-60.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-60@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-60@3x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-72.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-72@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-76.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-76@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-83.5@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small-50.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small-50@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon-Small@3x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/Icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/Icon@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/iTunesArtwork.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/iTunesArtwork.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/AppIcon/IconSet/iTunesArtwork@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/AppIcon/IconSet/iTunesArtwork@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/Screenshot/Calculator00.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/Screenshot/Calculator00.gif
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/Screenshot/Calculator01.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/Screenshot/Calculator01.gif
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/Screenshot/Calculator02.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/Screenshot/Calculator02.gif
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/Screenshot/Calculator03.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/Screenshot/Calculator03.gif
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/Screenshot/Calculator04.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/Screenshot/Calculator04.gif
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/Screenshot/Calculator05.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/Screenshot/Calculator05.gif
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/Screenshot/Calculator06.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/Screenshot/Calculator06.gif
--------------------------------------------------------------------------------
/problemsets/assignment-1/Art/Screenshot/Calculator07.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Art/Screenshot/Calculator07.gif
--------------------------------------------------------------------------------
/problemsets/assignment-1/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | ## Post an Issue
4 |
5 | If you discover a bug or error, please [add an issue](https://github.com/duliodenis/cs193p-Spring-2016/issues) here on GitHub. Feature requests are welcome. However, I am a one-man band, so pull requests are preferred.
6 |
7 |
8 | ## Create a Pull Request
9 |
10 | Fork the project, create a branch, commit your changes, and then create a pull request. Please submit your pull request to the **develop** branch of this repository.
11 |
12 | The **master** branch is for production-ready content and should not contain incomplete features. Development occurs on the **develop** branch. Once your pull request is accepted, it will be merged into **master**.
13 |
14 |
15 | ## Licensing
16 | Vending Machine is licensed under [the MIT License](LICENSE).
17 |
18 | ## Support or Contact
19 | Visit [ddApps.co](http://ddapps.co) to see more.
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Calculator
4 | //
5 | // Created by Dulio Denis on 5/1/16.
6 | // Copyright © 2016 Dulio Denis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-Small@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-Small@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "40x40",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-40@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-40@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "60x60",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-60@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-60@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "29x29",
41 | "idiom" : "ipad",
42 | "filename" : "Icon-Small.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "29x29",
47 | "idiom" : "ipad",
48 | "filename" : "Icon-Small@2x-1.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "40x40",
53 | "idiom" : "ipad",
54 | "filename" : "Icon-40.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "40x40",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-40@2x-1.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "76x76",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-76.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "76x76",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-76@2x.png",
73 | "scale" : "2x"
74 | },
75 | {
76 | "size" : "83.5x83.5",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-83.5@2x.png",
79 | "scale" : "2x"
80 | }
81 | ],
82 | "info" : {
83 | "version" : 1,
84 | "author" : "xcode"
85 | }
86 | }
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-40.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-40@2x-1.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/problemsets/assignment-1/Calculator/Calculator/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/CalculatorBrain.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CalculatorBrain.swift
3 | // Calculator
4 | //
5 | // Created by Dulio Denis on 5/2/16.
6 | // Copyright © 2016 Dulio Denis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class CalculatorBrain {
12 |
13 | private var accumulator = 0.0
14 | private var memory = 0.0
15 |
16 | func setOperand(operand: Double) {
17 | accumulator = operand
18 | }
19 |
20 | private var operations: Dictionary = [
21 | "π" : Operation.Constant(M_PI),
22 | "e" : Operation.Constant(M_E),
23 | "±" : Operation.UnaryOperation({ -$0 }),
24 | "√" : Operation.UnaryOperation(sqrt),
25 | "x^2" : Operation.UnaryOperation({ pow($0, 2.0) }),
26 | "cos" : Operation.UnaryOperation(cos),
27 | "sin" : Operation.UnaryOperation(sin),
28 | "tan" : Operation.UnaryOperation(tan),
29 | "×" : Operation.BinaryOperation({ $0 * $1 }),
30 | "÷" : Operation.BinaryOperation({ $0 / $1 }),
31 | "+" : Operation.BinaryOperation({ $0 + $1 }),
32 | "-" : Operation.BinaryOperation({ $0 - $1 }),
33 | "=" : Operation.Equals
34 | ]
35 |
36 | private enum Operation {
37 | case Constant(Double)
38 | case UnaryOperation((Double) -> Double)
39 | case BinaryOperation((Double, Double) -> Double)
40 | case Equals
41 | }
42 |
43 | func performOperation(symbol: String) {
44 | if let operation = operations[symbol] {
45 | switch operation {
46 | case .Constant(let value):
47 | accumulator = value
48 | case .UnaryOperation(let function):
49 | accumulator = function(accumulator)
50 | case .BinaryOperation(let function):
51 | executePendingBinaryOperation()
52 | pending = PendingBinaryOperationInfo(binaryFunction: function, firstOperand: accumulator)
53 | case .Equals:
54 | executePendingBinaryOperation()
55 | }
56 | }
57 | }
58 |
59 | private func executePendingBinaryOperation() {
60 | if pending != nil {
61 | accumulator = pending!.binaryFunction(pending!.firstOperand, accumulator)
62 | pending = nil
63 | }
64 | }
65 |
66 | private var pending: PendingBinaryOperationInfo?
67 |
68 | private struct PendingBinaryOperationInfo {
69 | var binaryFunction: (Double, Double) -> Double
70 | var firstOperand: Double
71 | }
72 |
73 | var result: Double {
74 | get {
75 | return accumulator
76 | }
77 | }
78 |
79 | func clear() {
80 | accumulator = 0.0
81 | }
82 | }
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/RoundedButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RoundedButton.swift
3 | // Calculator
4 | //
5 | // Created by Dulio Denis on 5/7/16.
6 | // Copyright © 2016 Dulio Denis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class RoundedButton: UIButton {
12 |
13 | override func awakeFromNib() {
14 | layer.cornerRadius = 5.0
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/problemsets/assignment-1/Calculator/Calculator/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Calculator
4 | //
5 | // Created by Dulio Denis on 5/1/16.
6 | // Copyright © 2016 Dulio Denis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | @IBOutlet private weak var display: UILabel!
14 | @IBOutlet private weak var calculationTape: UILabel!
15 |
16 | private var userIsInTheMiddleOfTyping = false
17 | private var decimalUsed = false
18 |
19 | @IBAction private func touchDigit(sender: UIButton) {
20 | let digit = sender.currentTitle!
21 |
22 | if userIsInTheMiddleOfTyping {
23 |
24 | if digit == "." && decimalUsed == true {
25 | return
26 | } else if digit == "." && decimalUsed == false {
27 | decimalUsed = true
28 | }
29 |
30 | let textCurrentlyInDisplay = display.text!
31 | display.text = textCurrentlyInDisplay + digit
32 | } else {
33 | display.text = digit
34 | }
35 |
36 | userIsInTheMiddleOfTyping = true
37 | }
38 |
39 | // computed property is calculated when getting and setting
40 | private var displayValue: Double {
41 | get {
42 | return Double(display.text!)!
43 | }
44 |
45 | set {
46 | display.text = String(newValue)
47 | }
48 | }
49 |
50 | private var brain = CalculatorBrain()
51 |
52 | @IBAction private func performOperation(sender: UIButton) {
53 | if userIsInTheMiddleOfTyping {
54 | brain.setOperand(displayValue)
55 | userIsInTheMiddleOfTyping = false
56 | }
57 |
58 | if let mathematicalSymbol = sender.currentTitle {
59 | brain.performOperation(mathematicalSymbol)
60 | }
61 |
62 | displayValue = brain.result
63 | }
64 |
65 | @IBAction func clear(sender: AnyObject) {
66 | userIsInTheMiddleOfTyping = false
67 | decimalUsed = false
68 | brain.clear()
69 | displayValue = brain.result
70 | display.text = "0"
71 | }
72 | }
73 |
74 |
--------------------------------------------------------------------------------
/problemsets/assignment-1/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Dulio Denis
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/problemsets/assignment-1/README.md:
--------------------------------------------------------------------------------
1 | # CS193p - Assignment 1: Calculator
2 |
3 | An iOS 9 / Swift 2 Calculator App that recreates the demonstration given in lecture and then make some small enhancements.
4 |
5 | 
6 |
7 | ## Contributing
8 |
9 | See [CONTRIBUTING.md](CONTRIBUTING.md).
10 |
11 | ## Licensing
12 | Calculator is licensed under [the MIT License](LICENSE).
13 |
14 | ## Support or Contact
15 | Visit [ddApps.co](http://ddapps.co) to see more.
--------------------------------------------------------------------------------
/reading/Reading_1_Intro_to_Swift.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/reading/Reading_1_Intro_to_Swift.pdf
--------------------------------------------------------------------------------
/reading/Reading_2_More_Swift.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/reading/Reading_2_More_Swift.pdf
--------------------------------------------------------------------------------
/reading/Reading_3_The_Rest_of_Swift.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/reading/Reading_3_The_Rest_of_Swift.pdf
--------------------------------------------------------------------------------
/slides/Lecture-1-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-1-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-10-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-10-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-11-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-11-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-12-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-12-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-13-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-13-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-14-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-14-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-15-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-15-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-16-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-16-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-17-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-17-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-18-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-18-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-2-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-2-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-3-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-3-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-4-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-4-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-5-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-5-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-6-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-6-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-7-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-7-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-8-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-8-Slides.pdf
--------------------------------------------------------------------------------
/slides/Lecture-9-Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duliodenis/cs193p-Spring-2016/6f095651b4c27a13c558f7afe0c23920531ef313/slides/Lecture-9-Slides.pdf
--------------------------------------------------------------------------------