estimatedRowHeight

This commit is contained in:
Max Sokolov 2015-11-14 17:49:30 +03:00
parent 20c19fda50
commit 6ee01134ff
9 changed files with 101 additions and 41 deletions

View File

@ -35,7 +35,7 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
self.tableView = tableView
self.tableView.delegate = self
self.tableView.dataSource = self
NSNotificationCenter.defaultCenter().addObserver(self, selector: "didReceiveAction:", name: kActionPerformedNotificationKey, object: nil)
}
@ -43,8 +43,8 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
NSNotificationCenter.defaultCenter().removeObserver(self)
}
// MARK: Public methods
// MARK: Sections manipulation
public func appendSection(section: TableSectionBuilder) {
sections.append(section)
@ -69,7 +69,7 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
return sections[indexPath.section].builderAtIndex(indexPath.row)!
}
private func triggerAction(action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath) -> AnyObject? {
public func triggerAction(action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath) -> AnyObject? {
let builder = builderAtIndexPath(indexPath)
return builder.0.triggerAction(action, cell: cell, indexPath: indexPath, itemIndex: builder.1)
@ -103,10 +103,13 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
let cell = tableView.dequeueReusableCellWithIdentifier(builder.0.reusableIdentifier, forIndexPath: indexPath)
builder.0.triggerAction(.configure, cell: cell, indexPath: indexPath, itemIndex: builder.1)
return cell
}
}
extension TableDirector {
// MARK: UITableViewDataSource - section setup
public func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
@ -140,11 +143,14 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
return sections[section].footerHeight
}
}
extension TableDirector {
// MARK: UITableViewDelegate - actions
public func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
if triggerAction(.click, cell: cell, indexPath: indexPath) != nil {
@ -169,8 +175,14 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate
return triggerAction(.shouldHighlight, cell: tableView.cellForRowAtIndexPath(indexPath), indexPath: indexPath) as? Bool ?? true
}
public func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 300
}
public func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return triggerAction(.height, cell: nil, indexPath: indexPath) as? CGFloat ?? tableView.rowHeight
print(indexPath)
return triggerAction(.height, cell: nil, indexPath: indexPath) as? CGFloat ?? UITableViewAutomaticDimension
}
}

View File

@ -21,12 +21,14 @@
import UIKit
import Foundation
public typealias ReturnValue = AnyObject?
internal enum ActionHandler<I, C> {
case actionBlock((data: ActionData<I, C>) -> Void)
case actionReturnBlock((data: ActionData<I, C>) -> AnyObject)
case actionReturnBlock((data: ActionData<I, C>) -> AnyObject?)
func call(data: ActionData<I, C>) -> AnyObject {
func call(data: ActionData<I, C>) -> AnyObject? {
switch (self) {
case .actionBlock(let closure):
@ -45,23 +47,26 @@ public class TableRowBuilder<I, C where C: UITableViewCell> : RowBuilder {
private var actions = Dictionary<String, ActionHandler<I, C>>()
private var items = [I]()
public var reusableIdentifier: String
public var estimatedRowHeight: Float
public var numberOfRows: Int {
get {
return items.count
}
}
public init(item: I, id: String) {
public init(item: I, id: String, estimatedRowHeight: Float = 0) {
reusableIdentifier = id
self.estimatedRowHeight = estimatedRowHeight
items.append(item)
}
public init(items: [I]? = nil, id: String) {
public init(items: [I]? = nil, id: String, estimatedRowHeight: Float = 0) {
reusableIdentifier = id
self.estimatedRowHeight = estimatedRowHeight
if items != nil {
self.items.appendContentsOf(items!)
@ -94,7 +99,7 @@ public class TableRowBuilder<I, C where C: UITableViewCell> : RowBuilder {
return self
}
public func action(actionType: ActionType, closure: (data: ActionData<I, C>) -> AnyObject) -> Self {
public func action(actionType: ActionType, closure: (data: ActionData<I, C>) -> ReturnValue) -> Self {
actions[actionType.key] = .actionReturnBlock(closure)
return self
@ -116,12 +121,12 @@ public class TableRowBuilder<I, C where C: UITableViewCell> : RowBuilder {
*/
public class TableConfigurableRowBuilder<I, C: ConfigurableCell where C.Item == I, C: UITableViewCell> : TableRowBuilder<I, C> {
public init(item: I) {
super.init(item: item, id: C.reusableIdentifier())
public init(item: I, estimatedRowHeight: Float = 0) {
super.init(item: item, id: C.reusableIdentifier(), estimatedRowHeight: estimatedRowHeight)
}
public init(items: [I]? = nil) {
super.init(items: items, id: C.reusableIdentifier())
public init(items: [I]? = nil, estimatedRowHeight: Float = 0) {
super.init(items: items, id: C.reusableIdentifier(), estimatedRowHeight: estimatedRowHeight)
}
public override func triggerAction(actionType: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int) -> AnyObject? {

View File

@ -40,8 +40,8 @@ public enum ActionType {
var key: String {
switch (self) {
case .custom(let str):
return str
case .custom(let key):
return key
default:
return "_\(self)"
}
@ -112,6 +112,7 @@ public protocol RowBuilder {
var numberOfRows: Int { get }
var reusableIdentifier: String { get }
var estimatedRowHeight: Float { get }
func triggerAction(actionType: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int) -> AnyObject?
}

View File

@ -10,6 +10,7 @@
508B71841BF48DD300272920 /* TableSectionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508B71831BF48DD300272920 /* TableSectionBuilder.swift */; };
508B71861BF48E0D00272920 /* TableRowBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508B71851BF48E0D00272920 /* TableRowBuilder.swift */; };
DA1BCD0F1BF5472C00CC0479 /* TableDirector.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1BCD0E1BF5472C00CC0479 /* TableDirector.swift */; };
DA1BCD111BF7388C00CC0479 /* CustomTableActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1BCD101BF7388C00CC0479 /* CustomTableActions.swift */; };
DAB7EB2B1BEF787300D2AD5E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB7EB2A1BEF787300D2AD5E /* AppDelegate.swift */; };
DAB7EB2D1BEF787300D2AD5E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB7EB2C1BEF787300D2AD5E /* ViewController.swift */; };
DAB7EB301BEF787300D2AD5E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DAB7EB2E1BEF787300D2AD5E /* Main.storyboard */; };
@ -23,6 +24,7 @@
508B71831BF48DD300272920 /* TableSectionBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableSectionBuilder.swift; sourceTree = "<group>"; };
508B71851BF48E0D00272920 /* TableRowBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableRowBuilder.swift; sourceTree = "<group>"; };
DA1BCD0E1BF5472C00CC0479 /* TableDirector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableDirector.swift; sourceTree = "<group>"; };
DA1BCD101BF7388C00CC0479 /* CustomTableActions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomTableActions.swift; sourceTree = "<group>"; };
DAB7EB271BEF787300D2AD5E /* TabletDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TabletDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
DAB7EB2A1BEF787300D2AD5E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DAB7EB2C1BEF787300D2AD5E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
@ -68,6 +70,7 @@
DAB7EB2A1BEF787300D2AD5E /* AppDelegate.swift */,
DAB7EB2C1BEF787300D2AD5E /* ViewController.swift */,
DAB7EB3F1BEFD07E00D2AD5E /* ConfigurableTableViewCell.swift */,
DA1BCD101BF7388C00CC0479 /* CustomTableActions.swift */,
DAB7EB2E1BEF787300D2AD5E /* Main.storyboard */,
DAB7EB311BEF787300D2AD5E /* Assets.xcassets */,
DAB7EB331BEF787300D2AD5E /* LaunchScreen.storyboard */,
@ -165,6 +168,7 @@
DA1BCD0F1BF5472C00CC0479 /* TableDirector.swift in Sources */,
DAB7EB401BEFD07E00D2AD5E /* ConfigurableTableViewCell.swift in Sources */,
DAB7EB2B1BEF787300D2AD5E /* AppDelegate.swift in Sources */,
DA1BCD111BF7388C00CC0479 /* CustomTableActions.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="jN2-c3-xf5">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="jN2-c3-xf5">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
</dependencies>
<scenes>
<!--View Controller-->
@ -49,24 +49,41 @@
<rect key="frame" x="0.0" y="0.0" width="600" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="C3u-xz-sbM">
<rect key="frame" x="14" y="7" width="46" height="30"/>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="C3u-xz-sbM">
<rect key="frame" x="14" y="5" width="70" height="34"/>
<animations/>
<state key="normal" title="Button"/>
<constraints>
<constraint firstAttribute="width" constant="70" id="MSu-D8-6BO"/>
</constraints>
<state key="normal" title="Button">
<color key="titleColor" red="0.090196078430000007" green="0.3411764706" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="buttonClicked:" destination="GPe-Vu-z5d" eventType="touchUpInside" id="IbC-qw-alO"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wWp-hU-I3e">
<rect key="frame" x="92" y="12" width="498" height="21"/>
<animations/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<animations/>
<constraints>
<constraint firstItem="C3u-xz-sbM" firstAttribute="leading" secondItem="GMV-qL-pTv" secondAttribute="leading" constant="14" id="NH5-kD-7u8"/>
<constraint firstItem="C3u-xz-sbM" firstAttribute="centerY" secondItem="GMV-qL-pTv" secondAttribute="centerY" id="gVO-Ze-LDM"/>
<constraint firstItem="C3u-xz-sbM" firstAttribute="leading" secondItem="GMV-qL-pTv" secondAttribute="leading" constant="14" id="6j5-PX-P9O"/>
<constraint firstItem="C3u-xz-sbM" firstAttribute="centerY" secondItem="GMV-qL-pTv" secondAttribute="centerY" id="OU7-rr-jUL"/>
<constraint firstItem="wWp-hU-I3e" firstAttribute="top" secondItem="GMV-qL-pTv" secondAttribute="top" constant="12" id="azl-YD-xyA"/>
<constraint firstItem="wWp-hU-I3e" firstAttribute="leading" secondItem="C3u-xz-sbM" secondAttribute="trailing" constant="8" id="tDZ-be-hlD"/>
<constraint firstAttribute="bottom" secondItem="wWp-hU-I3e" secondAttribute="bottom" constant="10" id="w4b-rY-Vf2"/>
<constraint firstAttribute="trailing" secondItem="wWp-hU-I3e" secondAttribute="trailing" constant="10" id="wlJ-Ga-0f7"/>
</constraints>
</tableViewCellContentView>
<animations/>
<connections>
<outlet property="button" destination="C3u-xz-sbM" id="7KC-FU-lBA"/>
<outlet property="contentLabel" destination="wWp-hU-I3e" id="uo4-ez-ea8"/>
</connections>
</tableViewCell>
</prototypes>

View File

@ -15,6 +15,7 @@ class ConfigurableTableViewCell: UITableViewCell, ConfigurableCell {
typealias Item = String
@IBOutlet weak var button: UIButton!
@IBOutlet weak var contentLabel: UILabel!
static func reusableIdentifier() -> String {

View File

@ -0,0 +1,10 @@
//
// CustomTableActions.swift
// TabletDemo
//
// Created by Max Sokolov on 14/11/15.
// Copyright © 2015 Tablet. All rights reserved.
//
import UIKit
import Foundation

View File

@ -23,29 +23,39 @@ class ViewController: UIViewController {
data.cell?.textLabel?.text = "\(data.item)"
}
.action(.height) { data in
return 50
}
.action(.shouldHighlight) { data in
return false
}
let configurableRowBuilder = TableConfigurableRowBuilder<String, ConfigurableTableViewCell>(items: ["5", "6", "7", "8"])
let configurableRowBuilder = TableConfigurableRowBuilder<String, ConfigurableTableViewCell>(items: ["5", "6", "7", "8"], estimatedRowHeight: 300)
.action(.click) { data -> Void in
data.cell!.textLabel?.text = ""
print("click action indexPath: \(data.indexPath), item: \(data.item)")
}
.action(kConfigurableTableViewCellButtonClickedAction) { data in
.action(kConfigurableTableViewCellButtonClickedAction) { data -> Void in
print("custom action indexPath: \(data.indexPath), item: \(data.item)")
}
let sectionBuilder = TableSectionBuilder(headerTitle: "Tablet", footerTitle: "Deal with table view like a boss.", rowBuilders: [rowBuilder, configurableRowBuilder])
.action(.height) { data -> ReturnValue in
if data.item == "5" {
return 70
}
return nil
}
.action(.configure) { (data) -> Void in
data.cell!.contentLabel.text = "With iOS 8, Apple has internalized much of the work that previously had to be implemented by you prior to iOS 8. In order to allow the self-sizing cell mechanism to work, you must first set the rowHeight property on the table view to the constant UITableViewAutomaticDimension. Then, you simply need to enable row height estimation by setting the table view's estimatedRowHeight property to a nonzero value, for example"
//data.cell!.setNeedsUpdateConstraints()
//data.cell!.updateConstraintsIfNeeded()
}
let sectionBuilder = TableSectionBuilder(headerTitle: "Tablet", footerTitle: "Deal with table view like a boss.", rowBuilders: [configurableRowBuilder])
tableDirector.appendSection(sectionBuilder)
}
}
}
// вход со стороны кутузовского проспекта между домами 10 14 левее чайхоны, на охране сказать кодовое слово Магия - найти клуб лабиринт