1

Background I have an IOS application that can receive a real-time stream of data. I have implemented custom value objects to store/capture this data from a live stream. I now need to bind my custom data objects to the UI (mostly use tableviews and custom cell's that call into those custom object values).

Question How can I bind an array of custom object values to my UI using Bond, ReactiveKit, or other framework in Swift 3?

Example Code

public class Device {
    var name: String
    var status: String
}
public class DeviceController {
    var devices = Array<Device>()
    // more code to init/populate array of custom Device classes
}
public class CustomViewController: ... {
    var deviceController = DeviceController()
    var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // more code to register custom cell
}
public class CustomCell:UITableviewCell {
    @IBOutlet weak var deviceName: UILabel!
    @IBOutlet weak var deviceStatus: UILabel!
}
chwarr
  • 6,777
  • 1
  • 30
  • 57
Cameron
  • 11
  • 1
  • 3

1 Answers1

0

You use the delegate pattern, which is already set up for many UIKit elements including UITableView.

A UITableView has two properties that can be any object conforming to two protocols, specifically

var dataSource: UITableViewDataSource?
var delegate: UITableViewDelegate?

So for your UITableView, you assign an object to act as the dataSource and delegate. Often, but not always, one would make the containing ViewController both the dataSource and delegate.

override func viewDidLoad() {
    tableView.dataSource = self
    tableView.delegate = self
    ...
}

However, you first have to make the ViewController conform to those protocols.

public class CustomViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

Command click on the two conformance declarations and you'll be able to see the methods you have to add to your view controller to conform. They're pretty obvious what they do, and you'll probably be able to figure it out from there.

But specifically you need to add the numberOfRows, numberOfSections and this method, which is I think the one you're asking about.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // dequeue a cell for reuse
    // type cast the cell to your UITableViewCell subclass
    // set the device name and device status labels like so..

    cell.deviceName = deviceController.devices[indexPath.row].name
    cell.deviceStatus = deviceController.devices[indexPath.row].status
    return cell
}

From there, the tableView will automatically request the data when the subviews are laid out. If your data isn't all available instantly, you can call tableView.reloadData() when it is.

twiz_
  • 1,178
  • 10
  • 16
  • I already have the delegates coded/implemented very similar to the code you suggested. This technique works well when I call a REST API and populate my array of custom objects (which get assigned to a table cell). The issue is that I now have a real-time feed that streams into my app, which in turn I update those custom objects inside my array but my tableview cells have no knowledge as to when the custom object values are changing which is why I'm looking at ReactiveKit/Bond/other framework for binding data values to UI components – Cameron Jan 11 '17 at 03:14