Skip to content

Instantly share code, notes, and snippets.

@werediver
Last active August 20, 2016 07:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save werediver/05fd8d29be8a3eab1a3556e007107d6a to your computer and use it in GitHub Desktop.
Save werediver/05fd8d29be8a3eab1a3556e007107d6a to your computer and use it in GitHub Desktop.
How to get data from UITableView's cells?
import UIKit
import XCPlayground
// SKIP FOR NOW :)
protocol SmartCell {
associatedtype Model
static var reuseId: String { get }
func loadModel(m: Model)
}
extension SmartCell {
static var reuseId: String { return "\(self.dynamicType)" }
}
class DataSource<Cell: UITableViewCell where Cell: SmartCell>: NSObject, UITableViewDataSource {
var items: [Cell.Model]
init(items: [Cell.Model]) {
self.items = items
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(Cell.reuseId) as! Cell
cell.loadModel(items[indexPath.row])
return cell
}
}
/// Target-Action helper.
final class Action: NSObject {
private let _action: () -> ()
init(action: () -> ()) {
_action = action
super.init()
}
func action() {
_action()
}
}
// READ FROM HERE
class TextFieldCell: UITableViewCell, SmartCell, UITextFieldDelegate {
class Model {
let placeholder: String?
var text: String?
init(placeholder: String?, text: String? = nil) {
self.placeholder = placeholder
self.text = text
}
}
var model: Model? {
didSet {
textField.placeholder = model?.placeholder
textField.text = model?.text
}
}
let textField = UITextField()
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
private func commonInit() {
contentView.addSubview(textField)
textField.delegate = self
}
override func layoutSubviews() {
textField.frame = contentView.bounds.insetBy(dx: 15, dy: 8)
}
func loadModel(m: Model) {
model = m
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let text = (textField.text as NSString?)?.stringByReplacingCharactersInRange(range, withString: string)
// Update the model.
model?.text = text
return true
}
}
// Sample items.
let items = [
TextFieldCell.Model(placeholder: "1"),
TextFieldCell.Model(placeholder: "2"),
TextFieldCell.Model(placeholder: "3", text: "xxx"),
TextFieldCell.Model(placeholder: "4"),
TextFieldCell.Model(placeholder: "5"),
TextFieldCell.Model(placeholder: "6")
]
let dataSource = DataSource<TextFieldCell>(items: items)
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 320, height: 100))
tableView.registerClass(TextFieldCell.self, forCellReuseIdentifier: TextFieldCell.reuseId)
tableView.dataSource = dataSource
// This way we'll dump user input to the console.
let dumpAction = Action {
for m in items {
print(m.text)
}
}
let dumpButton = UIButton(type: .System)
dumpButton.frame = CGRect(x: 15, y: 108, width: 50, height: 20)
dumpButton.setTitle("Dump", forState: .Normal)
dumpButton.addTarget(dumpAction, action: #selector(dumpAction.action), forControlEvents: .TouchUpInside)
let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 136))
view.backgroundColor = .whiteColor()
view.addSubview(tableView)
view.addSubview(dumpButton)
XCPlaygroundPage.currentPage.liveView = view
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment