- Continue Calc Demo
- Learn about MVC
- Calc Cont:
- Array <T>
- "Computed" properties
- Switch
- Functions as types
- Closure syntax for defining functions "on the fly"
- Methods with the same name but different argument types
- Auto layout
- Demo
- Optionals automatically are initialized with nil
- ? vs. !
- If we had used a ? we would have to unwrap every instance
- ! unwraps everything from the start (implicitly unwrapped optional)
- Enter key
- Copy and paste "3" button
- Replace 3 with Return symbol found in Special Characters menu
- //Ctrl-drag from button to in class below last action, Action, Name: enter, Type: UIButton, Touch Up Inside, Argument: None
- //right click on button and disconnect enter button from appendDigit
- @IBAction func enter (){
- inMiddleOfTyping = false
- operandStack.append(displayValue)
- println("operandStack = \(operandStack)")
- }
- Above action func enter, var operandStack*(: Array<Double>) = Array<Double>()
- //if a type can be inferred, it should be
- //Need to convert string to double:
- Below action, var displayValue: Double {
- get{
- return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
- }
- set{
- display.text = "\(newValue)"
- inMiddleOfTyping = false
- }
- get{
- }
- Operation keys
- Copy and paste "9" button
- Right click on button and disconnect button from appendDigit
- Replace 9 with X symbol found in Special Characters menu
- Ctrl-drag from button to in class above var operandStack, Action, Name: operate, Type: UIButton, Touch Up Inside, Argument: Sender
- Copy and paste "X" button 3x and replace X with + - and divide symbols
- @IBAction func operate(sender: UIButton) {
- let operation = sender.currentTitle!
- if inMiddleOfTyping {
- enter()
- }
- switch operation {
- case "x": performOperation{ $0 * $1 }
- case "/": performOperation{ $1 / $0 }
- case "+": performOperation{ $0 + $1 }
- case "-": performOperation{ $1 - $0 }
- default: break
- }
- }
- func performOperation(operation: (Double, Double) -> Double){
- if operandStack.count >= 2 {
- displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
- enter()
- }
- if operandStack.count >= 2 {
- }
- Additional Operations
- Copy and Paste row of operation buttons and line up next to them
- Remove characters but leave buttons
- In bottom button label with Square Root symbol found in Special Characters menu
- in switch operation above default
- case " √": performOperation { sqrt($0)}
- Copy/Paste func performOperation and edit to make it take one Double
- func performOperation(operation: Double -> Double){
- if operandStack.count >= 1 {
- displayValue = operation(operandStack.removeLast())
- enter()
- }
- if operandStack.count >= 1 {
- }
- Layout
- Copy/Paste a number to fill the last button space, delete and remove appendDigit (try to make this a "." button)
- Select all of the buttons, make sure they are lined up to left edge and below the label
- In Add New Constraints menu
- check off Equal Widths
- check off Equal Heights
- make all beams for spacing solid
- make all sides of spacing 8
- Use warning labels to select "Apply to all views in container" and "Update Frame"
- This demo was not a good representation of MVC because all of the calculator functions are not really UI. I assume that we should have put them all in a separate swift file.
- MVC
- Model - What your application is, but not how it is displayed
- Controller - How your model is presented to the user (UI logic, specific)
- View - Your Controller's minions (generic UI elements )
- It's all about know where things should go and managing communication between the camps
- Model and View do NOT interact, Controller can always talk to either (only sorta vice verse)
- Controller to View is an Outlet
- Model is UI independent
- View elements are too generic to communicate with the Model
- View to Controller is blind and structured (Action to Target)
- Sometimes View needs to sync with the Controller (will, should, did) View doesn't know specifics so will delegate them to the Controller (the delegate is set via a protocol and is blind to class)
- Views should not own the data they are displaying: data should be in the Model, it has nothing to do with the UI (data at, count)
- View wants to know how much data there is, asks Controller for data source, Controller asks Model, Model tells Controller amount, Controller tells View the amount
- Model is UI independent, should not talk to Controller
- If Model needs to communicate changes to the Controller, it uses a radio station-like broadcast mechanism
- Notification & Key Value Observing (KVO): when a Model has a change it will broadcast that change and the Controllers and/or other Models will tune in to the stuff they are interested in. (Don't want a View to do this)
- In multiple view apps you will need more complicated MVC groups
- An entire MVC can work as a View for another MVC
Learning Swift
This blog is for me to keep track of and maybe help other people to learn the iOS programming language Swift.
I am working my way through the iTunes U course "CS193P: Developing iOS 8 Apps with Swift" from Stanford University and using The Swift Programming Language (Swift 2.2 Edition) from Apple.
Class 1
Platform Components
- Tools: XCode
- Languages: Swift (and Obj-C)
- Frameworks: Foundation, Core Data, UIKit: main framework , Core Motion, Map Kit
- Design Strategy: MVC - Master View Controller
Demo
- Build a Calculator
- Single View Application
- Product Name: Calculator
- Org Name: FisherMichaels
- Org ID: com.FisherMichaels
- Bundle ID: com.FisherMichaels.Calculator
- Language: Swift
- Device: Universal
- Storyboard
- Drag in Label to top left guidelines, resize to right guideline, Type "0", Right justify, 32 pt font, resize box to fit
- Ctrl-drag from label to View, Trailing Space to container margin, Ctrl-drag from label to View, Leading Space to container margin, Ctrl-drag from label to View, Top Space to container margin
- In Doc Outline, look for problem areas
- Update Constraints: Make it look like my arbitrary decisions said it was, rarely use this
- Reset to Suggested Constraints: Removes already set constraints
- Update Frames: Change the Label to how it should be
- Open Assistant Editor, clear out class ViewController{
- //Ctrl-drag from label to in class, Outlet, Name: display
- @IBOutlet weak var display: UILabel!
- }
- Drag in Button to mid-left, name "7", resize and embiggen font
- //Ctrl-drag from button to in class, Action, Name: appendDigit, Type: UIButton, Touch Up Inside, Argument: Sender
- @IBAction func appendDigit(sender: UIButton){
- var inMiddleOfTyping: Bool = false
- let digit = sender!.currentTitle
- if inMiddleOfTyping {
- display.text = display.text! + digit
- } else {
- display.text = digit
- inMiddleOfTyping = true
- }
- }
- Copy/Paste and guideline up to build numberpad, move whole pad and line up to below label, left
- Single View Application