Skip to content

Instantly share code, notes, and snippets.

@cfr
Forked from chriseidhof/AppDelegate.swift
Last active August 29, 2015 14:17
Show Gist options
  • Save cfr/3326ef5d6a015d12fe46 to your computer and use it in GitHub Desktop.
Save cfr/3326ef5d6a015d12fe46 to your computer and use it in GitHub Desktop.
//
// MyViewController.swift
// TypedTableViewControllers
//
// Created Chris Eidhof on 23/03/15.
// Edited by Stan Serebryakov on 25/03/15.
//
func undefined() { fatalError("undefined") }
func when(@autoclosure condition: Void -> Bool, @autoclosure trueBranch: Void -> Void) {
if condition() { trueBranch() }
}
class Box<A> {
let unbox: A
init(_ val: A) { unbox = val }
}
import UIKit
class MyViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
override init() {
super.init(nibName: "MyViewController", bundle: nil)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
var items: [Any] = [] {
didSet { when(tableView != nil, tableView.reloadData()) }
}
var item: (Int -> Any?) = { _ in undefined() }
var configureCell: (UITableViewCell, Any) -> () = { _ in undefined() }
let cellId = "CellId"
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: cellId)
}
}
extension MyViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
NSLog("\(item(indexPath.row))")
}
// MARK: - Table view data source
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellId) as! UITableViewCell
configureCell(cell, items[indexPath.row])
return cell
}
class func newMyViewController<A>(items: [A], configure: (UITableViewCell, A) -> Void) -> MyViewController {
var vc = MyViewController()
vc.items = items.map { Box($0) }
vc.configureCell = { cell, obj in
if let value = obj as? Box<A> {
configure(cell, value.unbox)
}
}
vc.item = { i in
if let item = vc.items[i] as? Box<A> {
return item.unbox
} else {
return nil
}
}
return vc
}
}
@cfr
Copy link
Author

cfr commented Mar 30, 2015

The fact you cannot subclass UITableViewController and init with XIB in Swift is a known bug, here is workaround from Xcode release notes:

@import UIKit;
@interface UITableViewController() // Extend UITableViewController to work around 19775924
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil NS_DESIGNATED_INITIALIZER ;
@end

@algal
Copy link

algal commented May 16, 2015

What's the reason for defining when here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment