height strategies improvements

This commit is contained in:
Max Sokolov 2016-06-07 01:56:41 +03:00
parent 66f318bb15
commit 229ef94c0e
11 changed files with 67 additions and 71 deletions

View File

@ -29,7 +29,7 @@ public protocol ConfigurableCell {
associatedtype T
static func reusableIdentifier() -> String
static func estimatedHeight() -> Float
static func estimatedHeight() -> CGFloat
static func defaultHeight() -> Float?
func configure(_: T)
}
@ -43,4 +43,8 @@ public extension ConfigurableCell where Self: UITableViewCell {
static func defaultHeight() -> Float? {
return nil
}
static func estimatedHeight() -> CGFloat {
return UITableViewAutomaticDimension
}
}

View File

@ -22,31 +22,19 @@ import UIKit
public protocol HeightStrategy {
func height<Item: Hashable, Cell: ConfigurableCell where Cell.T == Item, Cell: UITableViewCell>(item: Item, cell: Cell.Type) -> CGFloat
var tableView: UITableView? { get set }
func height<Item, Cell: ConfigurableCell where Cell.T == Item, Cell: UITableViewCell>(item: Item, indexPath: NSIndexPath, cell: Cell.Type) -> CGFloat
func estimatedHeight() -> CGFloat
}
public class AutolayoutHeightStrategy: HeightStrategy {
public func height<Item, Cell: ConfigurableCell where Cell.T == Item, Cell: UITableViewCell>(item: Item, cell: Cell.Type) -> CGFloat {
return UITableViewAutomaticDimension
}
public func estimatedHeight() -> CGFloat {
return 0
}
}
public class PrototypeHeightStrategy: HeightStrategy {
public weak var tableView: UITableView?
private var cachedHeights = [Int: CGFloat]()
private weak var tableView: UITableView?
public init(tableView: UITableView) {
self.tableView = tableView
}
public func height<Item: Hashable, Cell: ConfigurableCell where Cell.T == Item, Cell: UITableViewCell>(item: Item, cell: Cell.Type) -> CGFloat {
public func height<Item, Cell: ConfigurableCell where Cell.T == Item, Cell: UITableViewCell>(item: Item, indexPath: NSIndexPath, cell: Cell.Type) -> CGFloat {
guard let cell = tableView?.dequeueReusableCellWithIdentifier(Cell.reusableIdentifier()) as? Cell else { return 0 }

View File

@ -20,7 +20,13 @@
import UIKit
public protocol RowBuilder {
public protocol RowHeightCalculatable {
func rowHeight(index: Int, indexPath: NSIndexPath) -> CGFloat
func estimatedRowHeight(index: Int, indexPath: NSIndexPath) -> CGFloat
}
public protocol RowBuilder: RowHeightCalculatable {
var tableDirector: TableDirector? { get }
@ -30,8 +36,5 @@ public protocol RowBuilder {
func reusableIdentifier(index: Int) -> String
func rowHeight(index: Int) -> CGFloat
func estimatedRowHeight(index: Int) -> CGFloat
func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject?
}

View File

@ -22,26 +22,11 @@ import UIKit
public typealias ReturnValue = AnyObject?
public enum TableActionType {
case Click
case Custom(String)
}
public class TableRowAction<DataType, CellType> {
let type: TableActionType
public init(type: TableActionType, handler: (data: ActionData<DataType, CellType>) -> Void) {
self.type = type
}
}
/**
Responsible for building cells of given type and passing items to them.
*/
public class TableBaseRowBuilder<DataType, CellType where CellType: UITableViewCell> : RowBuilder {
public private(set) weak var tableDirector: TableDirector?
private var actions = [String: ActionHandler<DataType, CellType>]()
@ -71,11 +56,13 @@ public class TableBaseRowBuilder<DataType, CellType where CellType: UITableViewC
}
}
public func rowHeight(index: Int) -> CGFloat {
// MARK: - RowHeightCalculatable -
public func rowHeight(index: Int, indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
public func estimatedRowHeight(index: Int) -> CGFloat {
public func estimatedRowHeight(index: Int, indexPath: NSIndexPath) -> CGFloat {
return 44
}

View File

@ -90,12 +90,12 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
public func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let builder = builderAtIndexPath(indexPath)
return builder.0.estimatedRowHeight(builder.1)
return builder.0.estimatedRowHeight(builder.1, indexPath: indexPath)
}
public func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let builder = builderAtIndexPath(indexPath)
return builder.0.rowHeight(builder.1)
return builder.0.rowHeight(builder.1, indexPath: indexPath)
}
// MARK: UITableViewDataSource - configuration
@ -112,8 +112,6 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
let builder = builderAtIndexPath(indexPath)
let cell = tableView.dequeueReusableCellWithIdentifier(builder.0.reusableIdentifier(builder.1), forIndexPath: indexPath)
if cell.frame.size.width != tableView.frame.size.width {

View File

@ -25,6 +25,8 @@ import UIKit
*/
public class TableRowBuilder<DataType, CellType: ConfigurableCell where CellType.T == DataType, CellType: UITableViewCell> : TableBaseRowBuilder<DataType, CellType> {
private var heightStrategy: HeightStrategy?
public init(item: DataType) {
super.init(item: item, id: CellType.reusableIdentifier())
}
@ -33,6 +35,13 @@ public class TableRowBuilder<DataType, CellType: ConfigurableCell where CellType
super.init(items: items, id: CellType.reusableIdentifier())
}
public override func willUpdateDirector(director: TableDirector?) {
super.willUpdateDirector(director)
heightStrategy = PrototypeHeightStrategy()
heightStrategy?.tableView = director?.tableView
}
public override func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? {
if case .configure = action {
@ -41,7 +50,13 @@ public class TableRowBuilder<DataType, CellType: ConfigurableCell where CellType
return super.invoke(action: action, cell: cell, indexPath: indexPath, itemIndex: itemIndex, userInfo: userInfo)
}
public override func estimatedRowHeight(index: Int) -> CGFloat {
return CGFloat(CellType.estimatedHeight())
// MARK: - RowHeightCalculatable -
public override func rowHeight(index: Int, indexPath: NSIndexPath) -> CGFloat {
return heightStrategy?.height(item(index: index), indexPath: indexPath, cell: CellType.self) ?? 0
}
public override func estimatedRowHeight(index: Int, indexPath: NSIndexPath) -> CGFloat {
return CellType.estimatedHeight()
}
}

View File

@ -24,6 +24,21 @@ struct TabletNotifications {
static let CellAction = "TabletNotificationsCellAction"
}
public enum TableActionType {
case Click
case Custom(String)
}
public class TableRowAction<DataType, CellType> {
let type: TableActionType
public init(type: TableActionType, handler: (data: ActionData<DataType, CellType>) -> Void) {
self.type = type
}
}
/**
The actions that Tablet provides.
*/

View File

@ -103,6 +103,7 @@
children = (
DAC2D68C1C9D799E009E9C19 /* TableDirector.swift */,
DA08A0501CF3AB6100BBF1F8 /* RowBuilder.swift */,
DA9EA7341D06155E0021F650 /* HeightStrategy.swift */,
DAC2D68D1C9D799E009E9C19 /* TableBaseRowBuilder.swift */,
5058386D1CF62B0700224C58 /* TableRowBuilder.swift */,
DA539CC51D01D44500368ACB /* TableDynamicRowBuilder.swift */,
@ -110,7 +111,6 @@
DA08A04E1CF3AB0C00BBF1F8 /* ConfigurableCell.swift */,
DAC2D68F1C9D799E009E9C19 /* Tablet.swift */,
DA539C9E1CFB025C00368ACB /* Operators.swift */,
DA9EA7341D06155E0021F650 /* HeightStrategy.swift */,
);
name = Classes;
sourceTree = "<group>";

View File

@ -20,20 +20,19 @@ class MainController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let h = PrototypeHeightStrategy(tableView: tableView)
h.height("123", cell: StoryboardImageTableViewCell.self)
let rowBuilder = TableRowBuilder<String, StoryboardImageTableViewCell>(items: ["1", "1", "1", "1"])
.action(.click) { [unowned self] e in
self.performSegueWithIdentifier("headerfooter", sender: nil)
}
let rows2 = TableRowBuilder<String, StoryboardImageTableViewCell>(items: ["1", "1", "1", "1"])
let section = TableSectionBuilder(headerTitle: "", footerTitle: "", rows: [rowBuilder])
/*let rows2 = TableRowBuilder<String, StoryboardImageTableViewCell>(items: ["1", "1", "1", "1"])
let cellItem = RowItem<String, StoryboardImageTableViewCell>(item: "1")
let cellItem2 = RowItem<String, StoryboardImageTableViewCell>(item: "1")
@ -44,8 +43,6 @@ class MainController: UIViewController {
let b = TableDynamicRowBuilder(items: [cellItem, cellItem2, cellItem3])
rowBuilder
@ -58,10 +55,10 @@ class MainController: UIViewController {
.delete(indexes: [0], animated: .None)
.insert(["2"], atIndex: 0, animated: .None)
.update(index: 0, item: "", animated: .None)
.move([1, 2], toIndexes: [3, 4])
.move([1, 2], toIndexes: [3, 4])*/
let section = TableSectionBuilder(headerTitle: "", footerTitle: "", rows: [rowBuilder])
//tableView.moveRowAtIndexPath(<#T##indexPath: NSIndexPath##NSIndexPath#>, toIndexPath: <#T##NSIndexPath#>)
//tableView.deleteRowsAtIndexPaths(<#T##indexPaths: [NSIndexPath]##[NSIndexPath]#>, withRowAnimation: <#T##UITableViewRowAnimation#>)
@ -73,14 +70,11 @@ class MainController: UIViewController {
//tableView.deleteSections([], withRowAnimation: .None)
//tableView.insertSections([], withRowAnimation: .None)
tableDirector.performBatchUpdates {
}
//tableDirector.performBatchUpdates {
//}
tableDirector.append(section: section)
tableDirector += rowBuilder
tableDirector += rows2
}
}

View File

@ -22,11 +22,7 @@ class StoryboardImageTableViewCell: UITableViewCell, ConfigurableCell {
titleLabel.text = "Test"
subtitleLabel.text = "Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.Copyright © 2016 Tablet. All rights reserved.1"
}
static func estimatedHeight() -> Float {
return 140
}
override func layoutSubviews() {
super.layoutSubviews()

View File

@ -16,8 +16,4 @@ class StoryboardTableViewCell: UITableViewCell, ConfigurableCell {
func configure(value: T) {
textLabel?.text = value
}
static func estimatedHeight() -> Float {
return 44
}
}