first try prototype cells

This commit is contained in:
Max Sokolov 2016-05-24 22:51:04 +03:00
parent b87d2b8aec
commit bba29151ec
5 changed files with 53 additions and 19 deletions

View File

@ -22,13 +22,15 @@ import UIKit
public protocol RowBuilder {
var reusableIdentifier: String { get }
var numberOfRows: Int { get }
var tableDirector: TableDirector? { get }
var reusableIdentifier: String { get }
var numberOfRows: Int { get }
var estimatedRowHeight: CGFloat { get }
func rowHeight(index: Int) -> CGFloat
func willUpdateDirector(director: TableDirector?)
func rowHeight(index: Int) -> CGFloat
func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject?
func registerCell(inTableView tableView: UITableView)
}

View File

@ -25,16 +25,16 @@ import UIKit
*/
public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
public unowned let tableView: UITableView
public private(set) weak var tableView: UITableView?
public weak var scrollDelegate: UIScrollViewDelegate?
private var sections = [TableSectionBuilder]()
public init(tableView: UITableView) {
super.init()
self.tableView = tableView
super.init()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView?.delegate = self
self.tableView?.dataSource = self
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(didReceiveAction), name: TabletNotifications.CellAction, object: nil)
}
@ -77,7 +77,7 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
func didReceiveAction(notification: NSNotification) {
if let action = notification.object as? Action, indexPath = tableView.indexPathForCell(action.cell) {
if let action = notification.object as? Action, indexPath = tableView?.indexPathForCell(action.cell) {
let builder = builderAtIndexPath(indexPath)
builder.0.invoke(action: .custom(action.key), cell: action.cell, indexPath: indexPath, itemIndex: builder.1, userInfo: notification.userInfo)
@ -145,7 +145,7 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
}
public func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let builder = builderAtIndexPath(indexPath)
return builder.0.rowHeight(builder.1)
}

View File

@ -27,6 +27,8 @@ public typealias ReturnValue = AnyObject?
*/
public class TableBaseRowBuilder<DataType, CellType where CellType: UITableViewCell> : RowBuilder {
public private(set) weak var tableDirector: TableDirector?
private var actions = [String: ActionHandler<DataType, CellType>]()
private var items = [DataType]()
@ -56,7 +58,7 @@ public class TableBaseRowBuilder<DataType, CellType where CellType: UITableViewC
}
public func rowHeight(index: Int) -> CGFloat {
return 0
return UITableViewAutomaticDimension
}
// MARK: - Chaining actions -
@ -86,8 +88,8 @@ public class TableBaseRowBuilder<DataType, CellType where CellType: UITableViewC
}
return nil
}
public func registerCell(inTableView tableView: UITableView) {
private func registerCell(inTableView tableView: UITableView) {
if tableView.dequeueReusableCellWithIdentifier(reusableIdentifier) != nil {
return
@ -102,6 +104,12 @@ public class TableBaseRowBuilder<DataType, CellType where CellType: UITableViewC
tableView.registerClass(CellType.self, forCellReuseIdentifier: reusableIdentifier)
}
}
public func willUpdateDirector(director: TableDirector?) {
tableDirector = director
}
// MARK: - Items manipulation -
@ -144,6 +152,14 @@ public class TablePrototypeRowBuilder<DataType: Hashable, CellType: Configurable
private var cachedHeights = [Int: CGFloat]()
private var prototypeCell: CellType?
public init(item: DataType) {
super.init(item: item, id: CellType.reusableIdentifier())
}
public init(items: [DataType]? = nil) {
super.init(items: items, id: CellType.reusableIdentifier())
}
public override func rowHeight(index: Int) -> CGFloat {
@ -154,8 +170,8 @@ public class TablePrototypeRowBuilder<DataType: Hashable, CellType: Configurable
if let height = cachedHeights[item.hashValue] {
return height
}
// TODO: set bounds to cell
cell.bounds = CGRectMake(0, 0, tableDirector?.tableView?.bounds.size.width ?? 0, cell.bounds.height)
cell.configure(item)
cell.setNeedsLayout()
@ -163,9 +179,25 @@ public class TablePrototypeRowBuilder<DataType: Hashable, CellType: Configurable
let height = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height + 1
cachedHeights[item.hashValue] = height
return height
}
public override func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? {
if case .configure = action {
(cell as? CellType)?.configure(items[itemIndex])
}
return super.invoke(action: action, cell: cell, indexPath: indexPath, itemIndex: itemIndex, userInfo: userInfo)
}
public override func willUpdateDirector(director: TableDirector?) {
tableDirector = director
if let tableView = director?.tableView, cell = tableView.dequeueReusableCellWithIdentifier(reusableIdentifier) as? CellType {
prototypeCell = cell
}
}
}
public func +=<DataType, CellType>(left: TableBaseRowBuilder<DataType, CellType>, right: DataType) {

View File

@ -29,7 +29,7 @@ public class TableSectionBuilder {
weak var tableDirector: TableDirector? {
didSet {
guard let director = tableDirector else { return }
builders.forEach { $0.registerCell(inTableView: director.tableView) }
builders.forEach { $0.willUpdateDirector(director) }
}
}
@ -79,7 +79,7 @@ public class TableSectionBuilder {
public func append(rows rows: [RowBuilder]) {
if let tableView = tableDirector?.tableView { rows.forEach { $0.registerCell(inTableView: tableView) } }
if let director = tableDirector { rows.forEach { $0.willUpdateDirector(director) } }
builders.appendContentsOf(rows)
}

View File

@ -21,7 +21,7 @@ class MainController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let rows = TableRowBuilder<String, StoryboardTableViewCell>(items: ["1", "2", "3"])
let rows = TablePrototypeRowBuilder<String, StoryboardTableViewCell>(items: ["1"])
.action(.click) { [unowned self] e in
self.performSegueWithIdentifier("headerfooter", sender: nil)
}