Skip to content

Commit

Permalink
add DTTableViewOptionalManageable protocol to allow optional tableVie…
Browse files Browse the repository at this point in the history
…w property.
  • Loading branch information
DenTelezhkin committed Sep 22, 2016
1 parent 9f7dee1 commit 6ddb359
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## Next

### Added

* `DTTableViewOptionalManageable` protocol, that is identical to `DTTableViewManageable`, but allows optional `tableView` property instead of implicitly unwrapped one.

## [5.0.0-beta.1](https://github.com/DenHeadless/DTTableViewManager/releases/tag/5.0.0-beta.1)

This is a major release, written in Swift 3. Read [Migration guide](Documentation/DTTableViewManager 5.0 migration guide.md) with descriptions of all features and changes.
Expand Down
2 changes: 1 addition & 1 deletion Carthage/Checkouts/DTModelStorage
2 changes: 1 addition & 1 deletion Carthage/Checkouts/Nimble
51 changes: 47 additions & 4 deletions Source/DTTableViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public protocol DTTableViewManageable : class, NSObjectProtocol
var tableView : UITableView! { get }
}

/// This protocol is similar to `DTTableViewManageable`, but allows using optional `UITableView` property.
public protocol DTTableViewOptionalManageable : class, NSObjectProtocol {
var tableView : UITableView? { get }
}

/// This key is used to store `DTTableViewManager` instance on `DTTableViewManageable` class using object association.
private var DTTableViewManagerAssociatedKey = "DTTableViewManager Associated Key"

Expand All @@ -60,18 +65,39 @@ extension DTTableViewManageable
}
}

extension DTTableViewOptionalManageable {
/// Lazily instantiated `DTTableViewManager` instance. When your table view is loaded, call startManagingWithDelegate: method and `DTTableViewManager` will take over UITableView datasource and delegate. Any method, that is not implemented by `DTTableViewManager`, will be forwarded to delegate.
/// - SeeAlso: `startManagingWithDelegate:`
public var manager : DTTableViewManager
{
get {
var object = objc_getAssociatedObject(self, &DTTableViewManagerAssociatedKey)
if object == nil {
object = DTTableViewManager()
objc_setAssociatedObject(self, &DTTableViewManagerAssociatedKey, object, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
return object as! DTTableViewManager
}
set {
objc_setAssociatedObject(self, &DTTableViewManagerAssociatedKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}

/// `DTTableViewManager` manages many of `UITableView` datasource and delegate methods and provides API for managing your data models in the table. Any method, that is not implemented by `DTTableViewManager`, will be forwarded to delegate.
/// - SeeAlso: `startManagingWithDelegate:`
open class DTTableViewManager : NSObject {

/// Internal weak link to `UITableView`
final fileprivate var tableView : UITableView?
{
return self.delegate?.tableView
if let delegate = delegate as? DTTableViewManageable { return delegate.tableView }
if let delegate = delegate as? DTTableViewOptionalManageable { return delegate.tableView }
return nil
}

/// `DTTableViewManageable` delegate.
final fileprivate weak var delegate : DTTableViewManageable?
final fileprivate weak var delegate : AnyObject?

/// Bool property, that will be true, after `startManagingWithDelegate` method is called on `DTTableViewManager`.
open var isManagingTableView : Bool {
Expand Down Expand Up @@ -155,8 +181,25 @@ open class DTTableViewManager : NSObject {
guard let tableView = delegate.tableView else {
preconditionFailure("Call startManagingWithDelegate: method only when UITableView has been created")
}

self.delegate = delegate
startManaging(with: tableView)
}

/// Starts managing `UITableView`.
///
/// Call this method before calling any of `DTTableViewManager` methods.
/// - Precondition: UITableView instance on `delegate` should not be nil.
/// - Note: If delegate is `DTViewModelMappingCustomizable`, it will also be used to determine which view-model mapping should be used by table view factory.
open func startManaging(withDelegate delegate : DTTableViewOptionalManageable)
{
guard let tableView = delegate.tableView else {
preconditionFailure("Call startManagingWithDelegate: method only when UITableView has been created")
}
self.delegate = delegate
startManaging(with: tableView)
}

fileprivate func startManaging(with tableView: UITableView) {
tableView.delegate = self
tableView.dataSource = self
if let mappingDelegate = delegate as? ViewModelMappingCustomizing {
Expand All @@ -180,7 +223,7 @@ open class DTTableViewManager : NSObject {
///
/// - Precondition: UITableView instance on `delegate` should not be nil.
open func coreDataUpdater() -> TableViewUpdater {
guard let tableView = delegate?.tableView else {
guard let tableView = tableView else {
preconditionFailure("Call startManagingWithDelegate: method only when UITableView has been created")
}
return TableViewUpdater(tableView: tableView,
Expand Down
12 changes: 12 additions & 0 deletions Tests/CreationTestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,20 @@ class FooCell : UITableViewCell, ModelTransfer
}
}

class OptionalTableViewController : UIViewController, DTTableViewOptionalManageable {
var tableView: UITableView?
}

class CreationTestCase: XCTestCase {

func testManagingWithOptionalTableViewWorks() {
let controller = OptionalTableViewController()
controller.tableView = UITableView()
controller.manager.startManaging(withDelegate: controller)

expect(controller.manager.isManagingTableView).to(beTrue())
}

func testCreatingTableControllerFromCode()
{
let controller = DTTestTableViewController()
Expand Down

0 comments on commit 6ddb359

Please sign in to comment.