By Kevin Hou
5 minute read
I was instructed to integrate HealthKit information — specifically pulling steps data — into Breathometer's upcoming app. I'm realitively new to Swift having only started a month ago, so this project was a way for me to get more familiar with the language and IDE. My task was to pull the data from HealhtKit then populate a table within a page of the app. This data could then be used for visualizations, analysis, etc. Here are my main learning goals for this project:
Create a table view property
1@IBOutlet weak var tableView: UITableView! // Connect to the storyboard element 2
Initialize the class and connect it to the storyboard.
1class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { ... }
2
Setup different UITableView properties
1// Imperative
2func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
3 return 0
4}
5
6// Imperative
7func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
8 return UITableViewCell()
9}
10
11func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
12 // Triggered when you select the row at indexPath
13}
14
You must also link the table view dataSource and delegate to the view controller like so:
In the view controller/tableviewdelegate/datasource class, you must register the class for the table view:
1override func viewDidLoad() {
2 super.viewDidLoad()
3
4 self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
5// tableView.setup(scrollable: false) // Turn off scrolling
6}
7
First step is to declare the data. In this case we’re going to use dummy data:
1var items: [String] = ["Hello", "World", "Swift"]
2
Using this data, we can now set the number of rows in our table view by calling the function:
1func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
2 return items.count
3}
4
1func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
2 var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
3
4 cell.textLabel?.text = self.items[indexPath.row]
5
6 return cell
7}
8
1func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
2 println("You selected cell #\(indexPath.row)!")
3}
4
1class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
2 @IBOutlet
3 var tableView: UITableView
4 var items: [String] = ["We", "Heart", "Swift"]
5
6 override func viewDidLoad() {
7 super.viewDidLoad()
8
9 self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
10 }
11
12
13 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
14 return self.items.count;
15 }
16
17 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
18 var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
19
20 cell.textLabel?.text = self.items[indexPath.row]
21
22 return cell
23 }
24
25 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
26 println("You selected cell #\(indexPath.row)!")
27 }
28}
29
By default, all table view cells have the text label and detail label values. To create a custom cell with more than just those two labels, follow these steps:
Drag a Table View Cell onto your UITableView. This will automatically generate a cell labeled “Prototype” that contains a nested content view. Treat this content view as any other view and drag UI elements like text fields, images, etc. onto the content view.
Now, create a new Swift file for the UITableViewCell class to connect your Table View Cell to some code. Initialize the class like so:
1class StepsCell: UITableViewCell {
2 // IB Outlets go here:
3
4 override func awakeFromNib() {
5 super.awakeFromNib()
6 // Initialization code
7 }
8
9 override func setSelected(selected: Bool, animated: Bool) {
10 super.setSelected(selected, animated: animated)
11
12 // Configure the view for the selected state
13 }
14}
15
Hook up the UI elements in the content view with IBOutlets in your UITableViewCell class. It’s identical to how you would do this for any other view controller. You can add constraints, stack views, etc. Just treat the content view as you would a blank view controller.
Now to access those UI elements in your main Table View Controller, you must use the “dequeueReusableCellWithIdentifier” command. Dequeue basically describes the manner in which data loads and unloads. If you imagine the scrolling items as a wheel, as the topmost item disappears, it reappears on the bottom. The table view is endlessly recycling the same x number of cells. This is a good approach for memory management especially when dealing with 100+ cells. Once you’ve stored the cell, you can then modify the various UI elements and return the cell to populate the table view.
1func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
2 var cell = self.tableView.dequeueReusableCellWithIdentifier("StepsCell")! as! StepsCell // Same identifier as class name
3 cell.dateLabel.text = "January \(indexPath)"
4 cell.textLabel?.text = String(indexPath)
5 return cell
6}
7
For populating table views with data from asynchronous requests, it can be helpful to reload your table view once you know all your data is complete
1// Reload in main queue 2dispatch_async(dispatch_get_main_queue(), { () -> Void in 3 self.tableView.reloadData() // Reload 4}) 5
Tutorial from: https://www.weheartswift.com/how-to-make-a-simple-table-view-with-ios-8-and-swift