git-swift-todo-tutorial
- Foreword
- Installing This App
- Feedback
- Getting Start: The Basics
- Getting Our Views Together: The storyboard
- Getting Our Hands Dirty: The swift
- Create a custom view controller that is a subclass of UIViewController
- Create a custom table view controller that is a subclass of UITableViewController
- Connecting cancel and done buttons to exit segue
- Create a Data Class
- Code a Data Class called TodoItem
- Give your table view controller an array of TodoItems
- Mark item as complete
- Lastly - add new items
- That's it!
Foreword
- We are obligated by an NDA not to post any screenshots. Sorry! We'll add them when the NDA lifts.
- Much of xCode 6 is in flux - we are developing for xCode 6 Beta 3. We will update as we go and update that message.
- This tutorial is based on apple's xcode 5 todo tutorial, which is an excellent place to look for auxilliary context (and screenshots!)
- Check out the Todo folder for the completed code
Installing This App
cd /your/preferred/xcode/location
git clone https://github.com/jadekler/git-swift-todo-tutorial.git
- Open xcode
- File > Open > /your/preferred/xcode/location/git-swift-todo-tutorial/Todo
Feedback
Please, provide feedback on anything you feel is lacking or could be better worded! Pull requests, github issues, or direct emails to [email protected] are all welcome!
Getting Start: The Basics
Create your project
- Open xCode
- Under iOS > Application, select 'Single View Application' and click Next
- Type 'Todo' as the Product Name, Swift as the Language, iPhone as the Devices, 'self' for Organization Identifier, and make sure Core Data is unchecked
- Save into a folder of your choosing
- Choose 'iPhone 4s' from the selection of devices at the top left of xCode
- Checkpoint: Hit the run button on the top left of xCode - you should see a blank white screen
Add a textfield to your storyboard
- In the Project Navigator on the far left of xCode, select Main.storyboard
- Find the Object Library at the bottom of the Utilities panel (which is on the far right of xCode). If you don't see the utilities panel, click the Utilities button at the top right
- At the bottom is a search panel. Find or search for 'Text Field'
- Drag one to the furthest left guider on your View, about 1/3 from the top of your view
- Increase the width of the text field by dragging the right side of the text view to the rightmost guider
- Next, let's change the placeholder text
- In the Utilities Slider on the right side of Xcode, find the Attributes Inspector (4th icon on the top bar from the left)
- Enter 'new todo' next to 'Placeholder'
- Checkpoint: Hit the run button on the top left of xCode - you should see a blank white screen with a text field that says 'New Todo' (don't worry if the text field goes off of the screen)
Getting Our Views Together: The storyboard
Position text field using Auto Layout
When you run your code, you can change orientation by going to 'Hardware' and clicking one of the rotate buttons. Note that when you do so, your text field doesn't adjust its size automatically. Let's address that.
- In the Project Navigator on the far left of xCode, select Main.storyboard
- Click on the Text Field in the View
- Set top space on the top
- Control+Click and Drag from the Text Field to the area right above, which should highlight blue and say 'View'
- Release your drag
- Select 'Top Space to Top Layout Guide' from the small black menu
- Set leading space on the left
- Control+Click and Drag from the Text Field to the area left of the view, which should highlight blue and say 'View'
- Release your drag
- Select 'Leading Space to Container' from the small black menu
- Set Trailing space on the right
- Control+Click and Drag from the Text Field to the area right of the view, which should highlight blue and say 'View'
- Release your drag
- Select 'Trailing Space to Container' from the small black menu
- Checkpoint: Hit the run button on the top left of xCode
- You should see the Text Field with equal spacing on each side and spacing from the top bar
- On the top bar of your computer click 'Hardware' and click 'Rotate Left' to enter landscape view
- The spacing from the left, right, and top sides should match the portrait view
Create a table view controller
- In the Project Navigator on the far left of xCode, select Main.storyboard
- Drag a table view controller and drop it into the canvas. If you're lacking in space, right click on the canvas to zoom out <make sure you're zoomed in to 100%>
Add a segue to navigate forward
- Select your Table View Controller
- With the view controller selected, choose Editor > Embed In > Navigation Controller
- In the canvas, select the newly created title area on your table view (or in the outline view select Navigation Item under Table View Controller)
- In the Attributes inspector, type 'My To-Do List' in the Title field
- Add a '+' button
- Drag a Bar Button Item object from the Object Library to the far right of the navigation bar in the table view controller
- Select the newly created bar button item
- Checkpoint: Hit the run button on the top left of xCode - you should see your newly created + button, but it won't do anything just yet 1. In the Attributes inspector, find the Identifier option in the Bar Button Item section. Choose 'Add' from the Identifier pop-up menu
- Checkpoint: Hit the run button on the top left of xCode - you should see your newly created + button, but it won't do anything just yet
Configure the Add button
- Control+Click and Drag from the Add button to the View Controller with the New Todo Text Field
- Release the drag
- Click 'present modally' from the small menu that appears
- Checkpoint: Hit the run button on the top left of xCode - Click the Add button and the New Todo view should appear, but there is no way to get back
Add a navigation controller to the view controller
- Select your view controller
Getting Our Hands Dirty: The swift
Create a custom view controller that is a subclass of UIViewController
- Choose File > New > File (or press Command-N)
- On the left of the dialog that appears, select the Cocoa Touch Class under iOS
- In the Class field, type 'AddTodoItemViewController'
- In the Language field, select Swift
- Choose UIViewController in the “Subclass of” pop-up menu
- Make sure the “Also create XIB file” option is unselected
- Click Next
- The save location will default to your project directory. Leave that as is
- The Group option will default to your app name, ToDoList. Leave that as is
- The Targets section will default to having your app selected and the tests for your app unselected. That’s perfect, so leave that as is
- Click Create
Now that you’ve created a custom view controller subclass, you need to tell your storyboard to use your custom class instead of the generic view controller.
- In the project navigator, select Main.storyboard
- Select your View Controller (in the Outline View, this is 'View Controller' under the 'Add a todo Scene')
- With the view controller selected, open the Identity inspector in the utility area.
- In the Identity inspector, open the pop-up menu next to the Class option
- Choose AddToDoItemViewController
Create a custom table view controller that is a subclass of UITableViewController
- Choose File > New > File (or press Command-N)
- On the left of the dialog that appears, select the Cocoa Touch Class under iOS
- In the Class field, type 'TodoListTableViewController'
- In the Language field, select Swift
- Choose UITableViewController in the “Subclass of” pop-up menu
- Make sure the “Also create XIB file” option is unselected
- Click Next
- The save location will default to your project directory. Leave that as is
- The Group option will default to your app name, ToDoList. Leave that as is
- The Targets section will default to having your app selected and the tests for your app unselected. That’s perfect, so leave that as is
- Click Create
- In the project navigator, select Main.storyboard
- Select your Table View Controller (in the Outline View, this is 'Table View Controller' under the 'Todo list Scene')
- With the table view controller selected, open the Identity inspector in the utility area.
- In the Identity inspector, open the pop-up menu next to the Class option
- Choose ToDoListTableViewController
Connecting cancel and done buttons to exit segue <reword?>
WHAT YOU SHOULD BE ABLE TO DO
- Navigate to your TodoListTableTableViewController.swift
- Add the following function (this registers the action and allows it to be used in storyboard):
@IBAction func unwindToList(segue: UIStoryboardSegue) {
println("Unwinding")
}
- Navigate to your storyboard
- On the canvas, Control-drag from the 'Cancel' button to the Exit item right above (the right item of the three squares above )
- Choose unwindToList: from the shortcut menu
- Do the same for the 'Done' button
- Checkpoint: Hit the run button on the top left of xCode - when you navigate over to Add a todo, your cancel and done buttons should pop you back over to Todo list (your table view)
WHAT YOU HAVE TO DO BECAUSE XCODE 6 IS BROKEN
(Note: see this stack overflow question for more details on this bug)
- Choose File > New > File (or press Command-N)
- On the left of the dialog that appears, select the Header File under iOS
- Save as 'TodoListTableViewController'
- Add the following to TodoListTableViewController.h:
@interface TodoListTableViewController
-(IBAction) unwindToList:(UIStoryboardSegue *) segue;
@end
This registers the action and allows it to be used in storyboard
- Navigate to TodoListTableViewController.swift
- Change the class definition to:
@objc(TodoListTableViewController) class TodoListTableViewController: UITableViewController {
This effectively makes it a C# class, which sucks, but there you go
- Add the Unwind function:
func unwindToList(segue: UIStoryboardSegue) {
}
- Re-register TodoListTableViewController, since we mucked about with it
- Go to your storyboard
- Click your table view controller
- Go to the Identity Inspector
- Pull down the dropdown and re-select TodoListTableViewController
- On the canvas, Control-drag from the 'Cancel' button to the Exit item right above (the right item of the three squares above )
- Choose unwindToList: from the shortcut menu
- Do the same for the 'Done' button
- Checkpoint: Hit the run button on the top left of xCode - when you navigate over to Add a todo, your cancel and done buttons should pop you back over to Todo list (your table view)
Create a Data Class
- Choose File > New > File
- In the iOS section on the left select Source
- Select Cocoa Touch Class and click Next
- Type ToDoItem in the Class field
- In the Subclass dropdown select NSObject
- Make sure Language is set to Swift and select Next
- Click Create Your class should look like this
import UIKit
class ToDoItem: NSObject {
}
Code a Data Class called TodoItem
- Give it a name and completed variable and initialize them like so:
import UIKit
class TodoItem: NSObject {
var itemName:String = ""
var completed:Bool = false
init(itemName:String) {
self.itemName = itemName
}
}
Give your table view controller an array of TodoItems
- Navigate to your TodoTableListViewController
- Give it an array of TodoItems:
var todoItems: [TodoItem] = []
- Give it an loadInitialData function that populates your array:
func loadInitialData() {
todoItems = [
TodoItem(itemName: "Go to the dentist"),
TodoItem(itemName: "Fetch groceries"),
TodoItem(itemName: "Sleep")
]
}
- Load your initial data from the viewDidLoad function:
override func viewDidLoad() {
super.viewDidLoad()
loadInitialData()
}
- Make the number of sections in your table one:
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return 1
}
- Next, let's create a function that returns the number of rows per section. Since we only have one section, we'll return a count of the todoItems. Add the following function:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return todoItems.count
}
<this function looks retarded because: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-XID_202 (go to External Parameter Names>
- The last function we need will genereate UITableViewCells for each row at a specific index
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("ListPrototypeCell") as UITableViewCell
var todoItem = todoItems[indexPath.row]
cell.textLabel.text = todoItem.itemName
return cell
}
- In the project navigator select Main.storyboard
- In the Todo list TableView select the Prototype Table View Cell
- In the Utilities slider on the right, go to the Attributes Inspector (4th icon from the left)
- For the Identifier change the Reuse Identifier to ListPrototypeCell <note: don't copy paste - type slowly and click out of box to make sure storyboard updates>
- Checkpoint - Run the app, the Table View should populate with the initial data "Go to the dentist", "Fetch groceries", "Sleep"
Mark item as complete
- In the project navigator select TodoListTableViewController.swift
- Create the override function tablView didSelectRowAtIndexPath
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
var tappedItem = todoItems[indexPath.row] as TodoItem
tappedItem.completed = !tappedItem.completed
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
}
- Add code to tableView cellForRowAtIndexPath to display checkmark on completed items
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("ListPrototypeCell") as UITableViewCell
var todoItem = todoItems[indexPath.row]
cell.textLabel.text = todoItem.itemName
if (todoItem.completed) {
cell.accessoryType = UITableViewCellAccessoryType.Checkmark;
} else {
cell.accessoryType = UITableViewCellAccessoryType.None;
}
return cell
}
- Checkpoint - run the app, click an item and a check mark should appear next to it, click it again to make the checkmark disappear
Lastly - add new items
- Head on over to your Storyboard
- In the outline view, select the AddTodoItemViewController object
- Click the Assistant button in the upper right of the window’s toolbar to open the assistant editor (the suit-looking icon)
- The editor on the right should appear with AddTodoItemViewController.swift displayed. If it isn’t displayed, click the filename in the editor on the right and choose AddTodoItemViewController.swift
- Select the text field in your storyboard
- Control-drag from the text field on your canvas to the code display in the editor on the right, stopping the drag at the line just below the
class AddTodoItemViewController: UIViewController {
line - In the dialog that appears, for Name, type textField and leave the rest of the options as they are
- Click Connect
- This will hook up your button to your code and create a connection in the storyboard xml for you. In your code it should look like
@IBOutlet var textField: UITextField
- Do the same for the Done button, calling it 'doneButton'. In your code it should look like
@IBOutlet var doneButton: UIBarButtonItem
- Next, let's give our controller a todoItem that it will store our 'add' data into:
var todoItem: TodoItem = TodoItem(itemName: "")
- Of course we also need to be able to take data from the user input and assign it to this variable:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject) {
if (self.textField.text.utf16count > 0) {
self.todoItem = TodoItem(itemName: self.textField.text)
}
}
- Lastly, we need to head back over to TodoListTableTableViewController.swift and update our unwindToList to take the data that AddTodoItemViewController.swift is holding and pop it into the array of todoItems:
func unwindToList(segue: UIStoryboardSegue) {
var source = segue.sourceViewController as AddTodoItemViewController
var todoItem:TodoItem = source.todoItem
if todoItem != nil {
self.todoItems += todoItem
self.tableView.reloadData()
}
}
- Checkpoint: Run your app - you should be able to add items!
That's it!
As mentioned before, we love feedback - please open issues about anything you feel is missing, or email the authors directly about questions or feedback at [email protected].