Compare commits

..

No commits in common. "master" and "2.6.0" have entirely different histories.

26 changed files with 107 additions and 562 deletions

View File

@ -1 +1 @@
5.7
4.0

View File

@ -1,5 +1,5 @@
language: objective-c
osx_image: xcode11
osx_image: xcode9
branches:
only:
- master
@ -7,15 +7,17 @@ env:
global:
- LC_CTYPE=en_US.UTF-8
- LANG=en_US.UTF-8
- IOS_SDK=iphonesimulator13.0
- IOS_SDK=iphonesimulator11.0
- SCHEME_IOS="TableKit"
- PROJECT_FRAMEWORK="TableKit.xcodeproj"
matrix:
- DESTINATION="OS=10.3.1,name=iPhone 5" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
- DESTINATION="OS=11.1,name=iPhone 6" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
- DESTINATION="OS=12.0,name=iPhone 7 Plus" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
- DESTINATION="OS=13.0,name=iPhone 11" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
- DESTINATION="OS=9.0,name=iPhone 6" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
- DESTINATION="OS=9.1,name=iPhone 6 Plus" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
- DESTINATION="OS=9.2,name=iPhone 6S" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
- DESTINATION="OS=9.3,name=iPhone 6S Plus" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
- DESTINATION="OS=10.0,name=iPhone 5" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
- DESTINATION="OS=10.0,name=iPhone 7 Plus" SCHEME="$SCHEME_IOS" SDK="$IOS_SDK"
script:
- set -o pipefail

View File

@ -2,18 +2,6 @@
All notable changes to this project will be documented in this file.
## [2.10.0](https://github.com/maxsokolov/TableKit/releases/tag/2.10.0)
Released on 2019-09-29.
- Swift 5.1 support.
## [2.9.0](https://github.com/maxsokolov/TableKit/releases/tag/2.9.0)
Released on 2019-04-04.
- Swift 5.0 support.
## [2.8.0](https://github.com/maxsokolov/TableKit/releases/tag/2.8.0)
Released on 2018-09-30.
- Swift 4.2 support.
## [2.5.0](https://github.com/maxsokolov/TableKit/releases/tag/2.5.0)
Released on 2017-09-24.
- Swift 4.0 support.

View File

@ -65,6 +65,6 @@ class AutolayoutCellsController: UIViewController {
view.setNeedsLayout()
view.layoutIfNeeded()
return view.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
return view.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
}
}

View File

@ -233,13 +233,13 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 1000;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = Tablet;
TargetAttributes = {
DAB7EB261BEF787300D2AD5E = {
CreatedOnToolsVersion = 7.0.1;
DevelopmentTeam = Z48R734SJX;
LastSwiftMigration = 1000;
LastSwiftMigration = 0800;
};
};
};
@ -248,7 +248,6 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
@ -339,14 +338,12 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@ -378,7 +375,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -394,14 +391,12 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@ -426,7 +421,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
VALIDATE_PRODUCT = YES;
};
name = Release;
@ -444,7 +439,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.tablekit.demo;
PRODUCT_NAME = TableKitDemo;
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -461,7 +456,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.tablekit.demo;
PRODUCT_NAME = TableKitDemo;
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Release;
};

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -1,19 +1,5 @@
// swift-tools-version:5.7
import PackageDescription
let package = Package(
name: "TableKit",
products: [
.library(
name: "TableKit",
targets: ["TableKit"]),
],
targets: [
.target(
name: "TableKit",
path: "Sources")
]
)
name: "TableKit"
)

View File

@ -2,9 +2,9 @@
<p align="left">
<a href="https://travis-ci.org/maxsokolov/TableKit"><img src="https://api.travis-ci.org/maxsokolov/TableKit.svg" alt="Build Status" /></a>
<a href="https://developer.apple.com/swift"><img src="https://img.shields.io/badge/Swift_5.1-compatible-4BC51D.svg?style=flat" alt="Swift 5.1 compatible" /></a>
<a href="https://developer.apple.com/swift"><img src="https://img.shields.io/badge/Swift_4.0-compatible-4BC51D.svg?style=flat" alt="Swift 4.0 compatible" /></a>
<a href="https://github.com/Carthage/Carthage"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat" alt="Carthage compatible" /></a>
<a href="https://cocoapods.org/pods/tablekit"><img src="https://img.shields.io/badge/pod-2.11.0-blue.svg" alt="CocoaPods compatible" /></a>
<a href="https://cocoapods.org/pods/tablekit"><img src="https://img.shields.io/badge/pod-2.6.0-blue.svg" alt="CocoaPods compatible" /></a>
<img src="https://img.shields.io/badge/platform-iOS-blue.svg?style=flat" alt="Platform iOS" />
<a href="https://raw.githubusercontent.com/maxsokolov/tablekit/master/LICENSE"><img src="http://img.shields.io/badge/license-MIT-blue.svg?style=flat" alt="License: MIT" /></a>
</p>
@ -204,7 +204,7 @@ tableDirector += rows
Done, your table is ready.
## Automatic cell registration
TableKit can register your cells in a table view automatically. In case if your reusable cell id matches cell's xib name:
TableKit can register your cells in a table view automatically. In case if your reusable cell id mathces cell's xib name:
```ruby
MyTableViewCell.swift
@ -237,7 +237,7 @@ Clone the repo and drag files from `Sources` folder into your Xcode project.
# Changelog
Keep an eye on [changes](CHANGELOG.md).
Keep eye on [changes](CHANGELOG.md).
# License

View File

@ -22,18 +22,13 @@ import UIKit
public protocol ConfigurableCell {
associatedtype CellData
associatedtype T
static var reuseIdentifier: String { get }
static var estimatedHeight: CGFloat? { get }
static var defaultHeight: CGFloat? { get }
static var layoutType: LayoutType { get }
func configure(with _: CellData)
func configure(with _: T)
}
public extension ConfigurableCell where Self: UITableViewCell {
@ -49,9 +44,4 @@ public extension ConfigurableCell where Self: UITableViewCell {
static var defaultHeight: CGFloat? {
return nil
}
static var layoutType: LayoutType {
return .auto
}
}

View File

@ -1,96 +0,0 @@
import UIKit
public extension TimeInterval {
static let defaultExpandableAnimationDuration: TimeInterval = 0.3
}
public protocol Expandable {
associatedtype ViewModelType: ExpandableCellViewModel
var viewModel: ViewModelType? { get }
func configure(state: ExpandableState)
}
extension Expandable where Self: UITableViewCell & ConfigurableCell {
public func initState() {
guard let viewModel = viewModel else {
return
}
changeState(expandableState: viewModel.expandableState)
}
private func changeState(expandableState: ExpandableState) {
// layout to get right frames, frame of bottom subview can be used to get expanded height
setNeedsLayout()
layoutIfNeeded()
// apply changes
configure(state: expandableState)
layoutIfNeeded()
}
public func toggleState(animated: Bool = true,
animationDuration: TimeInterval = .defaultExpandableAnimationDuration) {
guard let viewModel = viewModel,
let stateIndex = viewModel.availableStates.firstIndex(where: { $0 == viewModel.expandableState }) else {
return
}
let targetState = stateIndex == viewModel.availableStates.count - 1
? viewModel.availableStates[0]
: viewModel.availableStates[stateIndex + 1]
transition(to: targetState,
animated: animated,
animationDuration: animationDuration)
}
public func transition(to state: ExpandableState,
animated: Bool = true,
animationDuration: TimeInterval = .defaultExpandableAnimationDuration) {
guard let tableView = tableView,
let viewModel = viewModel,
viewModel.expandableState != state else {
return
}
let contentOffset = tableView.contentOffset
if animated {
UIView.animate(withDuration: animationDuration,
animations: { [weak self] in
self?.applyChanges(expandableState: state)
}, completion: { _ in
viewModel.expandableState = state
})
} else {
applyChanges(expandableState: state)
viewModel.expandableState = state
}
tableView.beginUpdates()
tableView.endUpdates()
tableView.setContentOffset(contentOffset, animated: false)
}
public func applyChanges(expandableState: ExpandableState) {
changeState(expandableState: expandableState)
if let indexPath = indexPath,
let tableDirector = (tableView?.delegate as? TableDirector),
let cellHeightCalculator = tableDirector.rowHeightCalculator as? ExpandableCellHeightCalculator {
cellHeightCalculator.updateCached(height: expandableState.height ?? height(layoutType: Self.layoutType), for: indexPath)
}
}
}

View File

@ -1,55 +0,0 @@
import UIKit
public final class ExpandableCellHeightCalculator: RowHeightCalculator {
private weak var tableView: UITableView?
private var prototypes = [String: UITableViewCell]()
private var cachedHeights = [IndexPath: CGFloat]()
public init(tableView: UITableView?) {
self.tableView = tableView
}
public func updateCached(height: CGFloat, for indexPath: IndexPath) {
cachedHeights[indexPath] = height
}
public func height(forRow row: Row, at indexPath: IndexPath) -> CGFloat {
guard let tableView = tableView else {
return 0
}
if let height = cachedHeights[indexPath] {
return height
}
var prototypeCell = prototypes[row.reuseIdentifier]
if prototypeCell == nil {
prototypeCell = tableView.dequeueReusableCell(withIdentifier: row.reuseIdentifier)
prototypes[row.reuseIdentifier] = prototypeCell
}
guard let cell = prototypeCell else {
return 0
}
row.configure(cell)
cell.layoutIfNeeded()
let height = cell.height(layoutType: row.layoutType)
cachedHeights[indexPath] = height
return height
}
public func estimatedHeight(forRow row: Row, at indexPath: IndexPath) -> CGFloat {
return height(forRow: row, at: indexPath)
}
public func invalidate() {
cachedHeights.removeAll()
}
}

View File

@ -1,15 +0,0 @@
public protocol ExpandableCellViewModel: AnyObject {
var expandableState: ExpandableState { get set }
var availableStates: [ExpandableState] { get }
}
public extension ExpandableCellViewModel {
var availableStates: [ExpandableState] {
return [.collapsed, .expanded]
}
}

View File

@ -1,41 +0,0 @@
import UIKit
public enum ExpandableState {
case collapsed
case expanded
case height(value: CGFloat)
}
extension ExpandableState: Equatable { }
extension ExpandableState {
public var isCollapsed: Bool {
guard case .collapsed = self else {
return false
}
return true
}
public var isExpanded: Bool {
guard case .expanded = self else {
return false
}
return true
}
public var height: CGFloat? {
guard case let .height(value: height) = self else {
return nil
}
return height
}
}

View File

@ -1,7 +0,0 @@
public enum LayoutType {
case manual
case auto
}

View File

@ -27,13 +27,13 @@ import UIKit
open class TableCellAction {
/// The cell that triggers an action.
public let cell: UITableViewCell
open let cell: UITableViewCell
/// The action unique key.
public let key: String
open let key: String
/// The custom user info.
public let userInfo: [AnyHashable: Any]?
open let userInfo: [AnyHashable: Any]?
public init(key: String, sender: UITableViewCell, userInfo: [AnyHashable: Any]? = nil) {

View File

@ -95,14 +95,6 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
tableView?.reloadData()
}
// MARK: - Private
private func row(at indexPath: IndexPath) -> Row? {
if indexPath.section < sections.count && indexPath.row < sections[indexPath.section].rows.count {
return sections[indexPath.section].rows[indexPath.row]
}
return nil
}
// MARK: Public
@discardableResult
open func invoke(
@ -110,13 +102,15 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
cell: UITableViewCell?, indexPath: IndexPath,
userInfo: [AnyHashable: Any]? = nil) -> Any?
{
guard let row = row(at: indexPath) else { return nil }
return row.invoke(
action: action,
cell: cell,
path: indexPath,
userInfo: userInfo
)
if indexPath.section < sections.count && indexPath.row < sections[indexPath.section].rows.count {
return sections[indexPath.section].rows[indexPath.row].invoke(
action: action,
cell: cell,
path: indexPath,
userInfo: userInfo
)
}
return nil
}
open override func responds(to selector: Selector) -> Bool {
@ -131,8 +125,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
// MARK: - Internal
func hasAction(_ action: TableRowActionType, atIndexPath indexPath: IndexPath) -> Bool {
guard let row = row(at: indexPath) else { return false }
return row.has(action: action)
return sections[indexPath.section].rows[indexPath.row].has(action: action)
}
@objc
@ -154,7 +147,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
return row.defaultHeight
?? row.estimatedHeight
?? rowHeightCalculator?.estimatedHeight(forRow: row, at: indexPath)
?? UITableView.automaticDimension
?? UITableViewAutomaticDimension
}
open func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
@ -170,7 +163,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
return rowHeight
?? row.defaultHeight
?? rowHeightCalculator?.height(forRow: row, at: indexPath)
?? UITableView.automaticDimension
?? UITableViewAutomaticDimension
}
// MARK: UITableViewDataSource - configuration
@ -179,8 +172,6 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
}
open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard section < sections.count else { return 0 }
return sections[section].numberOfRows
}
@ -205,44 +196,34 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
// MARK: UITableViewDataSource - section setup
open func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
guard section < sections.count else { return nil }
return sections[section].headerTitle
}
open func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
guard section < sections.count else { return nil }
return sections[section].footerTitle
}
// MARK: UITableViewDelegate - section setup
open func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard section < sections.count else { return nil }
return sections[section].headerView
}
open func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
guard section < sections.count else { return nil }
return sections[section].footerView
}
open func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
guard section < sections.count else { return 0 }
let section = sections[section]
return section.headerHeight ?? section.headerView?.frame.size.height ?? UITableView.automaticDimension
return section.headerHeight ?? section.headerView?.frame.size.height ?? UITableViewAutomaticDimension
}
open func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
guard section < sections.count else { return 0 }
let section = sections[section]
return section.footerHeight
?? section.footerView?.frame.size.height
?? UITableView.automaticDimension
?? UITableViewAutomaticDimension
}
// MARK: UITableViewDataSource - Index
@ -276,6 +257,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
// MARK: UITableViewDelegate - actions
open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
if invoke(action: .click, cell: cell, indexPath: indexPath) != nil {
@ -302,141 +284,68 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate {
}
open func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if hasAction(.willSelect, atIndexPath: indexPath) {
return invoke(action: .willSelect, cell: tableView.cellForRow(at: indexPath), indexPath: indexPath) as? IndexPath
}
return indexPath
}
open func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? {
if hasAction(.willDeselect, atIndexPath: indexPath) {
return invoke(action: .willDeselect, cell: tableView.cellForRow(at: indexPath), indexPath: indexPath) as? IndexPath
}
return indexPath
}
@available(iOS 13.0, *)
open func tableView(
_ tableView: UITableView,
shouldBeginMultipleSelectionInteractionAt indexPath: IndexPath) -> Bool
{
invoke(action: .shouldBeginMultipleSelection, cell: tableView.cellForRow(at: indexPath), indexPath: indexPath) as? Bool ?? false
}
@available(iOS 13.0, *)
open func tableView(
_ tableView: UITableView,
didBeginMultipleSelectionInteractionAt indexPath: IndexPath)
{
invoke(action: .didBeginMultipleSelection, cell: tableView.cellForRow(at: indexPath), indexPath: indexPath)
}
@available(iOS 13.0, *)
open func tableView(
_ tableView: UITableView,
contextMenuConfigurationForRowAt indexPath: IndexPath,
point: CGPoint) -> UIContextMenuConfiguration?
{
invoke(action: .showContextMenu, cell: tableView.cellForRow(at: indexPath), indexPath: indexPath, userInfo: [TableKitUserInfoKeys.ContextMenuInvokePoint: point]) as? UIContextMenuConfiguration
}
// MARK: - Row editing
open func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return sections[indexPath.section].rows[indexPath.row].isEditingAllowed(forIndexPath: indexPath)
}
open func tableView(_ tableView: UITableView,
leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let currentRow = sections[indexPath.section].rows[indexPath.row]
let configuration = UISwipeActionsConfiguration(actions: currentRow.leadingContextualActions)
configuration.performsFirstActionWithFullSwipe = currentRow.performsFirstActionWithFullSwipe
return configuration
}
open func tableView(_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let currentRow = sections[indexPath.section].rows[indexPath.row]
let configuration = UISwipeActionsConfiguration(actions: currentRow.trailingContextualActions)
configuration.performsFirstActionWithFullSwipe = currentRow.performsFirstActionWithFullSwipe
return configuration
open func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
return sections[indexPath.section].rows[indexPath.row].editingActions
}
open func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
if invoke(action: .canDelete, cell: tableView.cellForRow(at: indexPath), indexPath: indexPath) as? Bool ?? false {
return UITableViewCell.EditingStyle.delete
}
open func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
return UITableViewCell.EditingStyle.none
}
public func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
public func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
return invoke(action: .canMoveTo, cell: tableView.cellForRow(at: sourceIndexPath), indexPath: sourceIndexPath, userInfo: [TableKitUserInfoKeys.CellCanMoveProposedIndexPath: proposedDestinationIndexPath]) as? IndexPath ?? proposedDestinationIndexPath
}
open func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
invoke(action: .clickDelete, cell: tableView.cellForRow(at: indexPath), indexPath: indexPath)
}
}
open func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return invoke(action: .canMove, cell: tableView.cellForRow(at: indexPath), indexPath: indexPath) as? Bool ?? false
}
open func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
invoke(action: .move, cell: tableView.cellForRow(at: sourceIndexPath), indexPath: sourceIndexPath, userInfo: [TableKitUserInfoKeys.CellMoveDestinationIndexPath: destinationIndexPath])
}
open func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
invoke(action: .accessoryButtonTap, cell: cell, indexPath: indexPath)
}
}
// MARK: - Sections manipulation
extension TableDirector {
@discardableResult
public func append(section: TableSection) -> Self {
open func append(section: TableSection) -> Self {
append(sections: [section])
return self
}
@discardableResult
public func append(sections: [TableSection]) -> Self {
open func append(sections: [TableSection]) -> Self {
self.sections.append(contentsOf: sections)
return self
}
@discardableResult
public func append(rows: [Row]) -> Self {
open func append(rows: [Row]) -> Self {
append(section: TableSection(rows: rows))
return self
}
@discardableResult
public func insert(section: TableSection, atIndex index: Int) -> Self {
open func insert(section: TableSection, atIndex index: Int) -> Self {
sections.insert(section, at: index)
return self
}
@discardableResult
public func replaceSection(at index: Int, with section: TableSection) -> Self {
open func replaceSection(at index: Int, with section: TableSection) -> Self {
if index < sections.count {
sections[index] = section
}
@ -444,20 +353,20 @@ extension TableDirector {
}
@discardableResult
public func delete(sectionAt index: Int) -> Self {
open func delete(sectionAt index: Int) -> Self {
sections.remove(at: index)
return self
}
@discardableResult
public func remove(sectionAt index: Int) -> Self {
open func remove(sectionAt index: Int) -> Self {
return delete(sectionAt: index)
}
@discardableResult
public func clear() -> Self {
open func clear() -> Self {
rowHeightCalculator?.invalidate()
sections.removeAll()
@ -467,7 +376,7 @@ extension TableDirector {
// MARK: - deprecated methods
@available(*, deprecated, message: "Use 'delete(sectionAt:)' method instead")
@discardableResult
public func delete(index: Int) -> Self {
open func delete(index: Int) -> Self {
sections.remove(at: index)
return self

View File

@ -26,21 +26,16 @@ struct TableKitNotifications {
public struct TableKitUserInfoKeys {
public static let CellMoveDestinationIndexPath = "TableKitCellMoveDestinationIndexPath"
public static let CellCanMoveProposedIndexPath = "CellCanMoveProposedIndexPath"
public static let ContextMenuInvokePoint = "ContextMenuInvokePoint"
}
public protocol RowConfigurable {
func configure(_ cell: UITableViewCell)
}
public protocol RowActionable {
var leadingContextualActions: [UIContextualAction] { get }
var trailingContextualActions: [UIContextualAction] { get }
var performsFirstActionWithFullSwipe: Bool { get }
var editingActions: [UITableViewRowAction]? { get }
func isEditingAllowed(forIndexPath indexPath: IndexPath) -> Bool
func invoke(
@ -61,8 +56,7 @@ public protocol Row: RowConfigurable, RowActionable, RowHashable {
var reuseIdentifier: String { get }
var cellType: AnyClass { get }
var layoutType: LayoutType { get }
var estimatedHeight: CGFloat? { get }
var defaultHeight: CGFloat? { get }
}
@ -74,21 +68,13 @@ public enum TableRowActionType {
case select
case deselect
case willSelect
case willDeselect
case willDisplay
case didEndDisplaying
case shouldHighlight
case shouldBeginMultipleSelection
case didBeginMultipleSelection
case height
case canEdit
case configure
case canDelete
case canMove
case canMoveTo
case move
case showContextMenu
case accessoryButtonTap
case custom(String)
var key: String {

View File

@ -57,7 +57,7 @@ open class TablePrototypeCellHeightCalculator: RowHeightCalculator {
cell.setNeedsLayout()
cell.layoutIfNeeded()
let height = cell.contentView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height + (tableView.separatorStyle != .none ? separatorHeight : 0)
let height = cell.contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height + (tableView.separatorStyle != .none ? separatorHeight : 0)
cachedHeights[hash] = height
@ -78,7 +78,7 @@ open class TablePrototypeCellHeightCalculator: RowHeightCalculator {
return estimatedHeight
}
return UITableView.automaticDimension
return UITableViewAutomaticDimension
}
open func invalidate() {

View File

@ -21,21 +21,10 @@
import UIKit
open class TableRow<CellType: ConfigurableCell>: Row where CellType: UITableViewCell {
public let item: CellType.CellData
open let item: CellType.T
private lazy var actions = [String: [TableRowAction<CellType>]]()
open var leadingContextualActions: [UIContextualAction] {
[]
}
open var trailingContextualActions: [UIContextualAction] {
[]
}
open var performsFirstActionWithFullSwipe: Bool {
false
}
private(set) open var editingActions: [UITableViewRowAction]?
open var hashValue: Int {
return ObjectIdentifier(self).hashValue
@ -52,20 +41,15 @@ open class TableRow<CellType: ConfigurableCell>: Row where CellType: UITableView
open var defaultHeight: CGFloat? {
return CellType.defaultHeight
}
open var layoutType: LayoutType {
return CellType.layoutType
}
open var cellType: AnyClass {
return CellType.self
}
public init(item: CellType.CellData,
actions: [TableRowAction<CellType>]? = nil) {
public init(item: CellType.T, actions: [TableRowAction<CellType>]? = nil, editingActions: [UITableViewRowAction]? = nil) {
self.item = item
self.editingActions = editingActions
actions?.forEach { on($0) }
}
@ -75,12 +59,12 @@ open class TableRow<CellType: ConfigurableCell>: Row where CellType: UITableView
(cell as? CellType)?.configure(with: item)
}
// MARK: - RowActionable -
open func invoke(action: TableRowActionType, cell: UITableViewCell?, path: IndexPath, userInfo: [AnyHashable: Any]? = nil) -> Any? {
return actions[action.key]?.compactMap({ $0.invokeActionOn(cell: cell, item: item, path: path, userInfo: userInfo) }).last
return actions[action.key]?.flatMap({ $0.invokeActionOn(cell: cell, item: item, path: path, userInfo: userInfo) }).last
}
open func has(action: TableRowActionType) -> Bool {
@ -93,10 +77,7 @@ open class TableRow<CellType: ConfigurableCell>: Row where CellType: UITableView
if actions[TableRowActionType.canEdit.key] != nil {
return invoke(action: .canEdit, cell: nil, path: indexPath) as? Bool ?? false
}
return !leadingContextualActions.isEmpty
|| !trailingContextualActions.isEmpty
|| actions[TableRowActionType.clickDelete.key] != nil
return editingActions?.isEmpty == false || actions[TableRowActionType.clickDelete.key] != nil
}
// MARK: - actions -
@ -132,7 +113,7 @@ open class TableRow<CellType: ConfigurableCell>: Row where CellType: UITableView
open func removeAction(forActionId actionId: String) {
for (key, value) in actions {
if let actionIndex = value.firstIndex(where: { $0.id == actionId }) {
if let actionIndex = value.index(where: { $0.id == actionId }) {
actions[key]?.remove(at: actionIndex)
}
}

View File

@ -22,12 +22,12 @@ import UIKit
open class TableRowActionOptions<CellType: ConfigurableCell> where CellType: UITableViewCell {
public let item: CellType.CellData
public let cell: CellType?
public let indexPath: IndexPath
public let userInfo: [AnyHashable: Any]?
open let item: CellType.T
open let cell: CellType?
open let indexPath: IndexPath
open let userInfo: [AnyHashable: Any]?
init(item: CellType.CellData, cell: CellType?, path: IndexPath, userInfo: [AnyHashable: Any]?) {
init(item: CellType.T, cell: CellType?, path: IndexPath, userInfo: [AnyHashable: Any]?) {
self.item = item
self.cell = cell
@ -55,7 +55,7 @@ private enum TableRowActionHandler<CellType: ConfigurableCell> where CellType: U
open class TableRowAction<CellType: ConfigurableCell> where CellType: UITableViewCell {
open var id: String?
public let type: TableRowActionType
open let type: TableRowActionType
private let handler: TableRowActionHandler<CellType>
public init(_ type: TableRowActionType, handler: @escaping (_ options: TableRowActionOptions<CellType>) -> Void) {
@ -76,7 +76,7 @@ open class TableRowAction<CellType: ConfigurableCell> where CellType: UITableVie
self.handler = .action(handler)
}
public func invokeActionOn(cell: UITableViewCell?, item: CellType.CellData, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? {
public func invokeActionOn(cell: UITableViewCell?, item: CellType.T, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? {
return handler.invoke(withOptions: TableRowActionOptions(item: item, cell: cell as? CellType, path: path, userInfo: userInfo))
}

View File

@ -1,32 +0,0 @@
import UIKit
extension UITableViewCell {
var tableView: UITableView? {
var view = superview
while view != nil && !(view is UITableView) {
view = view?.superview
}
return view as? UITableView
}
var indexPath: IndexPath? {
guard let indexPath = tableView?.indexPath(for: self) else {
return nil
}
return indexPath
}
public func height(layoutType: LayoutType) -> CGFloat {
switch layoutType {
case .auto:
return contentView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
case .manual:
return contentView.subviews.map { $0.frame.maxY }.max() ?? 0
}
}
}

View File

@ -2,16 +2,16 @@ Pod::Spec.new do |s|
s.name = 'TableKit'
s.module_name = 'TableKit'
s.version = '2.12'
s.version = '2.6.0'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/TableKit'
s.homepage = 'https://github.com/maxsokolov/TableKit'
s.summary = 'Type-safe declarative table views with Swift.'
s.author = { 'Max Sokolov' => 'i@maxsokolov.net' }
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.platforms = { :ios => '12.0' }
s.ios.deployment_target = '12.0'
s.platforms = { :ios => '8.0' }
s.ios.deployment_target = '8.0'
s.source_files = 'Sources/*.swift'
s.source = { :git => 'https://git.svc.touchin.ru/TouchInstinct/TableKit.git', :tag => s.version }
s.source = { :git => 'https://github.com/maxsokolov/TableKit.git', :tag => s.version }
end

View File

@ -7,12 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
2CBFA2F521F692F100147B56 /* ExpandableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBFA2F421F692F100147B56 /* ExpandableState.swift */; };
3201E78421BE9DE1001DF9E7 /* ExpandableCellHeightCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3201E78321BE9DE1001DF9E7 /* ExpandableCellHeightCalculator.swift */; };
3201E78621BE9E25001DF9E7 /* UITableViewCell+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3201E78521BE9E25001DF9E7 /* UITableViewCell+Extensions.swift */; };
3201E78821BE9EB2001DF9E7 /* Expandable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3201E78721BE9EB2001DF9E7 /* Expandable.swift */; };
3201E78A21BE9ED4001DF9E7 /* ExpandableCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3201E78921BE9ED4001DF9E7 /* ExpandableCellViewModel.swift */; };
32BDFE9F21C167F400D0BBB4 /* LayoutType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BDFE9E21C167F400D0BBB4 /* LayoutType.swift */; };
50CF6E6B1D6704FE004746FF /* TableCellRegisterer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */; };
50E858581DB153F500A9AA55 /* TableKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E858571DB153F500A9AA55 /* TableKit.swift */; };
DA9EA7AF1D0EC2C90021F650 /* ConfigurableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */; };
@ -38,12 +32,6 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
2CBFA2F421F692F100147B56 /* ExpandableState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableState.swift; sourceTree = "<group>"; };
3201E78321BE9DE1001DF9E7 /* ExpandableCellHeightCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableCellHeightCalculator.swift; sourceTree = "<group>"; };
3201E78521BE9E25001DF9E7 /* UITableViewCell+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableViewCell+Extensions.swift"; sourceTree = "<group>"; };
3201E78721BE9EB2001DF9E7 /* Expandable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Expandable.swift; sourceTree = "<group>"; };
3201E78921BE9ED4001DF9E7 /* ExpandableCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableCellViewModel.swift; sourceTree = "<group>"; };
32BDFE9E21C167F400D0BBB4 /* LayoutType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutType.swift; sourceTree = "<group>"; };
50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableCellRegisterer.swift; sourceTree = "<group>"; };
50E858571DB153F500A9AA55 /* TableKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableKit.swift; sourceTree = "<group>"; };
DA9EA7561D0B679A0021F650 /* TableKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TableKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -102,22 +90,16 @@
DA9EA7A51D0EC2B90021F650 /* Sources */ = {
isa = PBXGroup;
children = (
DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */,
3201E78321BE9DE1001DF9E7 /* ExpandableCellHeightCalculator.swift */,
DA9EA7A81D0EC2C90021F650 /* Operators.swift */,
DA9EA7A91D0EC2C90021F650 /* TableCellAction.swift */,
50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */,
DA9EA7AA1D0EC2C90021F650 /* TableDirector.swift */,
50E858571DB153F500A9AA55 /* TableKit.swift */,
DA9EA7A71D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift */,
DA9EA7AA1D0EC2C90021F650 /* TableDirector.swift */,
50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */,
DA9EA7AB1D0EC2C90021F650 /* TableRow.swift */,
DA9EA7AC1D0EC2C90021F650 /* TableRowAction.swift */,
DA9EA7AE1D0EC2C90021F650 /* TableSection.swift */,
3201E78521BE9E25001DF9E7 /* UITableViewCell+Extensions.swift */,
3201E78721BE9EB2001DF9E7 /* Expandable.swift */,
3201E78921BE9ED4001DF9E7 /* ExpandableCellViewModel.swift */,
32BDFE9E21C167F400D0BBB4 /* LayoutType.swift */,
2CBFA2F421F692F100147B56 /* ExpandableState.swift */,
DA9EA7A91D0EC2C90021F650 /* TableCellAction.swift */,
DA9EA7A71D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift */,
DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */,
DA9EA7A81D0EC2C90021F650 /* Operators.swift */,
);
path = Sources;
sourceTree = "<group>";
@ -195,16 +177,16 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 1000;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = "Max Sokolov";
TargetAttributes = {
DA9EA7551D0B679A0021F650 = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 1000;
LastSwiftMigration = 0800;
};
DA9EA7C31D0EC45F0021F650 = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 1000;
LastSwiftMigration = 0800;
};
};
};
@ -213,7 +195,6 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = DA9EA74C1D0B679A0021F650;
@ -249,19 +230,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3201E78A21BE9ED4001DF9E7 /* ExpandableCellViewModel.swift in Sources */,
50CF6E6B1D6704FE004746FF /* TableCellRegisterer.swift in Sources */,
DA9EA7AF1D0EC2C90021F650 /* ConfigurableCell.swift in Sources */,
DA9EA7B31D0EC2C90021F650 /* TableDirector.swift in Sources */,
3201E78821BE9EB2001DF9E7 /* Expandable.swift in Sources */,
2CBFA2F521F692F100147B56 /* ExpandableState.swift in Sources */,
DA9EA7B71D0EC2C90021F650 /* TableSection.swift in Sources */,
DA9EA7B01D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift in Sources */,
3201E78421BE9DE1001DF9E7 /* ExpandableCellHeightCalculator.swift in Sources */,
DA9EA7B51D0EC2C90021F650 /* TableRowAction.swift in Sources */,
DA9EA7B21D0EC2C90021F650 /* TableCellAction.swift in Sources */,
32BDFE9F21C167F400D0BBB4 /* LayoutType.swift in Sources */,
3201E78621BE9E25001DF9E7 /* UITableViewCell+Extensions.swift in Sources */,
DA9EA7B11D0EC2C90021F650 /* Operators.swift in Sources */,
DA9EA7B41D0EC2C90021F650 /* TableRow.swift in Sources */,
50E858581DB153F500A9AA55 /* TableKit.swift in Sources */,
@ -300,14 +275,12 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@ -340,7 +313,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@ -360,14 +333,12 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@ -393,7 +364,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@ -418,7 +389,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -438,7 +409,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.tablekit.TableKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Release;
};
@ -450,7 +421,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.tablekit.TableKitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -462,7 +433,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.tablekit.TableKitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Release;
};

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
@ -55,6 +56,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@ -74,10 +74,7 @@ class TableKitTests: XCTestCase {
super.setUp()
testController = TestController()
testController.tableView.frame = UIScreen.main.bounds
testController.tableView.isHidden = false
testController.tableView.setNeedsLayout()
testController.tableView.layoutIfNeeded()
testController.view.isHidden = false
}
override func tearDown() {