Protocol-oriented UITableView management, powered by generics and associated types.

Overview

CI codecov.io CocoaPod platform CocoaPod version Swift Package Manager compatible Packagist

DTTableViewManager

Features

  • Powerful mapping system between data models and cells, headers and footers
  • Automatic datasource and interface synchronization.
  • Flexible Memory/CoreData/Realm/diffable datasource storage options
  • Powerful compile-time safe events system, that covers all of UITableView delegate methods
  • Views created from code, XIB, or storyboard, automatic registration and dequeue
  • Can be used with UITableViewController, or UIViewController with UITableView
  • Unified syntax with DTCollectionViewManager
  • Complete documentation
  • API Reference

Requirements

  • Xcode 12+
  • iOS 11.0+ / tvOS 11.0+ / macCatalyst 13.0+
  • Swift 5.3+

If you need Xcode 11 support or Swift 4...Swift 5.2, or iOS 8...iOS 10 support, you can use 7.x releases.

Installation

Swift Package Manager

Add package into Xcode Project settings -> Swift Packages

CocoaPods:

pod 'DTTableViewManager', '~> 10.0.0'

Quick start

Let's say you have an array of Posts you want to display in UITableView. To quickly show them using DTTableViewManager, here's what you need to do:

  1. Create UITableViewCell subclass, let's say PostCell and adopt ModelTransfer protocol:
class PostCell : UITableViewCell, ModelTransfer {
    func update(with model: Post) {
        // Fill your cell with actual data
    }
}
  1. In your view controller:
class PostsViewController: UITableViewController, DTTableViewManageable {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Register PostCell to be used with this controller's table view
        manager.register(PostCell.self)

        // Populate datasource
        manager.memoryStorage.setItems(posts)
    }
}    

Make sure your UITableView outlet is wired to your class (or use UITableViewController subclass). If you have a PostCell.xib file, it will be automatically used for dequeueing PostCell.

  1. That's it! It's that easy!

Of course, cool stuff does not stop there, framework supports all datasource and delegate methods as closures, conditional mappings and much much more! Choose what interests you in the next section of readme.

Burning questions

Starter pack
Advanced

Sample code and documentation

Thanks

  • Alexey Belkevich for providing initial implementation of CellFactory.
  • Michael Fey for providing insight into NSFetchedResultsController updates done right.
  • Nickolay Sheika for great feedback, that helped shaping 3.0 release and future direction of the library.
  • Artem Antihevich for great discussions about Swift generics and type capturing.
Comments
  • manager.whenSelected not work

    manager.whenSelected not work

    I use my custom cell class LabelCell in storyboard This is setup method

    func setupTable() {
        manager.startManagingWithDelegate(self)
        manager.registerCellClass(ParamValueCell.self)
        manager.whenSelected(ParamValueCell.self){ postCell, post, indexPath in
          print("Selected \(post) in \(postCell) at \(indexPath)")
        }
      }
    

    I fill cells and they appear in table but "manager.whenSelected" not work and
    print("Selected \(post) in \(postCell) at \(indexPath)") - never called

    In debug seems that fail in next place

    func reactionsOfType(type: UIReactionType, forView view: Any) -> [UIReaction] {
        ....
        //fail in this place
        reaction.viewClass == unwrappedView.dynamicType.
        ...
    }
    
    
    My cell class
    public struct LabelCellModel {  
      let labelValue: Variable<String>
    }
    
    public class LabelCell: TableViewCell, ModelTransfer {
    
      @IBOutlet weak var label: UILabel!
    
      public func updateWithModel(model: LabelCellModel) {
    
        model.labelValue.asObservable()
          .takeUntil(rx_reuse)
          .subscribeNext({[weak self] labelText in self?.label.text = labelText })
          .addDisposableTo(disposeBag)
      }
    }
    
    waiting for feedback question 
    opened by andrewSvsg 22
  • don't include Frameworks into DTTableViewManager.framework

    don't include Frameworks into DTTableViewManager.framework

    Otherwise iTunes Connect rejects app that embeds DTTableViewManager.framework

    [18:46:06]: ERROR ITMS-90206: "Invalid Bundle. The bundle at 'MyApp.app/Frameworks/DTModelStorage.framework' contains disallowed file 'Frameworks'."
    

    I'm using Carthage, but seems like CocoaPods might complain about EMBEDDED_CONTENT_CONTAINS_SWIFT = NO; There is an ongoing discussion in CocoaPods https://github.com/CocoaPods/CocoaPods/issues/4515

    opened by etataurov 10
  • Update Model in UITableViewCell class

    Update Model in UITableViewCell class

    Hi!

    In order to save state of the current cell, how to update the model (or any other approach) so to resume the state after scrolling.

    E.g: A very simple case, keep UIButton selected state in model class, so after each call of cellForRow, it can be reset to the desired state.

    What is equivalent to #this in DTTableViewManager?

    question 
    opened by EngrAhsanAli 7
  • heightForHeaderInSection call

    heightForHeaderInSection call

    Hi! Is it a bug that open func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat called?

    in simple implementation of UITableView with dataSource/delegate this method not call

    enhancement 
    opened by makleso6 7
  • Grouped table view's footer height

    Grouped table view's footer height

    Hello,

    how can I set the footer height of a normal grouped table view? Since I can't use the table's delegate methods anymore and I don't want to set a view for a model, I cannot find a way to do it otherwise.

    Thank you

    opened by davidevincenzi 7
  • Cell mapping is missing for model

    Cell mapping is missing for model

    Hello,

    I was getting following error.

    fatal error: Cell mapping is missing for model: Task(userId: 1, id: 1, title: "delectus aut autem", completed: false)

      {
        "id" : 199,
        "title" : "numquam repellendus a magnam",
        "userId" : 10,
        "completed" : true
      },
      {
        "id" : 200,
        "title" : "ipsam aperiam voluptates qui",
        "userId" : 10,
        "completed" : false
      }
    ]
    

    Cell mapping is missing for model: Task(userId: 1, id: 1, title: "delectus aut autem", completed: false) fatal error: Cell mapping is missing for model: Task(userId: 1, id: 1, title: "delectus aut autem", completed: false): file /Users/seyhunak/Projects/DemoTableViewManager/Pods/DTTableViewManager/Source/DTTableViewManager.swift, line 532

    Here is the my implementation.

    TaskViewController.swift

    let json: NSArray? = try response.mapJSON() as? NSArray
       if let json = json {
           let tasks: Array<Task>? = Mapper<Task>().mapArray(json)
    
           self.manager.memoryStorage.removeAllItems()
           self.manager.memoryStorage.addItems(tasks!, toSection: 0)
           self.tableView.reloadData()                        
    }
    
    

    Task.swift

    import Foundation
    import ObjectMapper
    
    // MARK: Initializer and Properties
    
    public struct Task: Mappable {
    
        var userId: Int!
        var id: Int!
        var title: String!
        var completed: Bool!
    
        // MARK: JSON
    
        public init?(_ map: Map) {
            mapping(map)
        }
    
        public mutating func mapping(map: Map) {
            userId <- map["userId"]
            id <- map["id"]
            title <- map["title"]
            completed <- map["completed"]
        }
    
    }
    

    Fyi @DenHeadless

    Thanks.

    opened by seyhunak 6
  • seeing recursion with DTCollectionViewDelegate canFocus

    seeing recursion with DTCollectionViewDelegate canFocus

    Sorry, this isn't really an issue, but asking for advice, as to whether you've seen this and might know the cause.

    There is a situation (which I'm still trying to determine the cause) where canFocus gets called repeatedly, and recursively. Screenshot attached of stacktrace. I'm sure it's some dumb issue on my part, just not sure best way to proceed.

    screen shot 2018-10-24 at 12 20 12 pm
    opened by skydivedan 5
  • I'm a dummy, but how to set section header?

    I'm a dummy, but how to set section header?

    I have:

    SearchResultSectionHeader - UIView with matching nib, implements ModelTransfer SearchResultSectionHeaderModel - Model for the above

    I've tried (in all combinations):

    manager.registerHeader(SearchResultSectionHeader.self) manager.memoryStorage.setSectionHeaderModel(SearchResultSectionHeader.self, forSection: 0) manager.memoryStorage.setSectionHeaderModel(SearchResultSectionHeaderModel.self, forSection: 0)

    Still can't see my custom section header view in the table. I have populated the table with cells. I must be doing something wrong, but what?

    opened by rablador 5
  • Using Carthage can't import RealmStorage

    Using Carthage can't import RealmStorage

    Following the readme directions but RealmStorage isn't accessible. Everything else is. Integrating with existing project. But not bridging to objc. Only using in swift.

    opened by ericlewis 5
  • Example project fails to build

    Example project fails to build

    There's probably just some setting that I'm forgetting to set, but it would be pretty ideal if you could just pull and run.

    Here's how I got/started the project:

    caesar at macbook in ~/Developer/scratch
    ○ git clone [email protected]:DenHeadless/DTTableViewManager.git
    Cloning into 'DTTableViewManager'...
    remote: Counting objects: 4106, done.
    remote: Compressing objects: 100% (6/6), done.
    remote: Total 4106 (delta 0), reused 0 (delta 0), pack-reused 4100
    Receiving objects: 100% (4106/4106), 1.67 MiB | 1.25 MiB/s, done.
    Resolving deltas: 100% (2580/2580), done.
    Checking connectivity... done.
    
    caesar at macbook in ~/Developer/scratch
    ○ cd DTTableViewManager/Example                         09/16/2015 10:57:53 JST
    
    caesar at macbook in ~/Developer/scratch/DTTableViewManager/Example on master
    ☿ pod install                                           09/16/2015 10:58:23 JST
    Updating local specs repositories
    
    CocoaPods 0.39.0.beta.4 is available.
    To update use: `sudo gem install cocoapods --pre`
    [!] This is a test version we'd love you to try.
    
    For more information see http://blog.cocoapods.org
    and the CHANGELOG for this version http://git.io/BaH8pQ.
    
    Analyzing dependencies
    Downloading dependencies
    Installing Cedar (0.11.3)
    Installing DTModelStorage (1.2.4)
    Installing OCMock (2.2.4)
    Generating Pods project
    Integrating client project
    
    [!] Please close any current Xcode sessions and use `DTTableViewManager.xcworkspace` for this project from now on.
    Sending stats
    
    caesar at macbook in ~/Developer/scratch/DTTableViewManager/Example on master!
    ☿ open DTTableViewManager.xcworkspace                   09/16/2015 10:58:39 JST
    

    Then build the Example target, and SectionModel+HeaderFooter.swift is telling me "No such module 'DTModelStorage'"

    Just thought I'd let you know. :)

    opened by cjwirth 5
  • crash when replacing items using `RealmStorage.setSection`, if amt items in new list don't match...

    crash when replacing items using `RealmStorage.setSection`, if amt items in new list don't match...

    Here's the scenario.

    I have a UITableView. (so, no cells). I call RealmStorage.setSection and pass in a List. At the moment that I do this, the list has 5 items in it. My table-view updates correctly, and draws all my cells. Great! Loving it.

    At some point down the road, I need to completely replace the entire contents of my table-view. So, I pass in a new List by calling RealmStorage.setSection again. This time the list is empty. (I'll be making a call to a webservice to get some data back later, but initially, the list is empty).

    This causes UITableView to crash. I get a bad index exception (trying to draw the first cell, but there shoud be no cells). So, it asks for data for index-0, but there is no data, so crash.

    Thankfully, I found a workaround: before calling setSection call realmStorage.deleteSections(IndexSet(integer: 0)) (I only have one section).

    The reason this works, is because (for reasons I don't understand) calling setSection does not convince UITableView that the amount of items in the datasource has changed, but deleteSections does. I can tell this, because numberOfRowsInSection is never called when I call setSection the second time. But it does get called when I delete the section, and call setSection again.

    If there's any better solution to this, I'd be happy to hear it.

    waiting for feedback 
    opened by skydivedan 4
  • Cannot build for simulator on M1 Mac

    Cannot build for simulator on M1 Mac

    When trying to build for simulator devices on an M1 mac, I get the following error: Could not find module 'DTModelStorage' for target 'x86_64-apple-ios-simulator'; found: arm64, arm64-apple-ios-simulator

    I am able to build and run on real devices as well as archive my project.

    wontfix help wanted 
    opened by bstillitano 3
Releases(11.0.0)
  • 11.0.0(Oct 6, 2022)

    Added

    • Support for UITableViewDelegate.tableView(_:canPerformPrimaryActionForRowAt:) and UITableViewDelegate.tableView(_:performPrimaryActionForRowAt:) delegate methods on iOS 16 and tvOS 16.
    • Support for UIHostingConfiguration on iOS 16 / tvOS 16 / macCatalyst 16:
    manager.registerHostingConfiguration(for: Post.self) { _, post, _ in
        UIHostingConfiguration {
            PostView(post: post)
        }
    }
    

    It's also possible to incorporate UIKit cell states by simply adding additional parameter to registration:

    manager.registerHostingConfiguration(for: Post.self) { state, _, post, _ in
        UIHostingConfiguration {
            PostView(post: post, isSelected: state.isSelected)
        }
    }
    
    • Support for events, wrapping UITableViewDataSourcePrefetching protocol.
    manager.register(PostCell.self) { mapping in
        mapping.prefetch { model, indexPath in }
        mapping.cancelPrefetch { model, indexPath in }
    }
    

    Please note, that while datasource methods are called once per array of indexPaths, events for models will be called individually, so single model (and indexPath) is passed to each event. Theoretically, this should make prefetching and cancellation easier, since you no longer need to walk through array and find all data models, you can operate on a single data model at a time.

    Deprecated

    • Cell / View events, registered with DTTableViewManager are soft-deprecated. Please use events in mapping instead:

    Deprecated:

        manager.register(PostCell.self)
        manager.didSelect(PostCell.self) { postCell, post, indexPath in }
    

    Recommended:

        manager.register(PostCell.self) { mapping in
            mapping.didSelect { postCell, post, indexPath in }
        }
    

    While previously main benefits for second syntax were mostly syntactic, now with support for SwiftUI it will be hard to actually specialize hosting cells (and might be impossible when iOS 16 hosting configuration is supported), so only second syntax will work for all kinds of cells, and first syntax can only work for non-SwiftUI cells. New delegate methods for UITableView (starting with iOS 16 / tvO 16 SDK) will be added only as extension to mapping protocols, not DTTableViewManager itself.

    Source code(tar.gz)
    Source code(zip)
  • 11.0.0-beta.1(Jul 11, 2022)

    Introducing support for SwiftUI!

    Registering SwiftUI views as content for table view cells:

    manager.registerHostingCell(for: Post.self) { model, indexPath in
        PostSwiftUIView(model: model)
    }
    

    This method is supported on iOS 13+ / tvOS 13+ / macCatalyst 13+.

    Please note, that this integration is not supported by Apple, therefore it comes with several workarounds, read more about those in SwiftUI support document

    Added

    • HostingCellViewModelMapping - CellViewModelMapping subclass to register mappings fro SwiftUI views.
    • HostingTableViewCell - UITableViewCell subclass , implementing container for SwiftUI view embedded into it.
    • HostingTableViewCellConfiguration - configuration for SwiftUI views hosting inside HostingTableViewCell.

    Changed

    • Event reactions are now defined in protocol extension instead of extending former ViewModelMapping class, thus allowing to call those methods not only for UIKit mappings, but SwiftUI-hosted cells as well.

    Breaking

    • ViewModelMapping class and it's protocol have been split into multiple classes and protocols for better subclassability (for example CellViewModelMapping / TableViewCellModelMapping). Please note, that while technically this is breaking, it's very unlikely to break anything in code, since this type is only present in mapping closures, and public interfaces did not change at all.
    Source code(tar.gz)
    Source code(zip)
  • 10.0.0(Dec 2, 2021)

    Added

    • Closure wrappers for iOS 15 tableView:selectionFollowsFocusForRowAt method.

    Changed

    • To align version numbers between DTModelStorage, DTTableViewManager and DTCollectionViewManager, DTTableViewManager will not have 9.x release, instead it's being released as 10.x.

    Removed

    • Wrappers for tableView:willCommitMenuWithAnimator delegate method, that was only briefly available in Xcode 12, and was removed by Apple in one of Xcode 12 releases.
    Source code(tar.gz)
    Source code(zip)
  • 9.0.0-beta.1(Jul 12, 2021)

  • 8.0.1(Mar 3, 2021)

  • 8.0.0-beta.1(Sep 2, 2020)

    Added

    • Cell and supplementary view events are now available inside mapping closure directly, for example:
    // Previous releases
    manager.register(PostCell.self)
    manager.didSelect(PostCell.self) { cell, model, indexPath in
        // React to selection
    }
    
    // New
    manager.register(PostCell.self) { mapping in
        mapping.didSelect { cell, model, indexPath in
    
        }
    }
    

    Those events are now tied to ViewModelMapping instance, which means, that events, registered this way, will only trigger, if mapping condition of current mapping applies. For example:

    manager.register(PostCell.self) { mapping in
        mapping.condition = .section(0)
        mapping.didSelect { cell, model, indexPath in  
            // This closure will only get called, when user selects cell in the first section
        }
    }
    manager.register(PostCell.self) { mapping in
        mapping.condition = .section(1)
        mapping.didSelect { cell, model, indexPath in  
            // This closure will only get called, when user selects cell in the second section
        }
    }
    

    Please note, that headers and footers only support mapping-style event registration, if they inherit from UITableViewHeaderFooterView.

    • TableViewConfiguration semanticHeaderHeight and semanticFooterHeight, that specify whether DTTableViewManager should deploy custom logic in tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) and tableView(_ tableView: UITableView, heightForFooterInSection section: Int). This logic includes checking whether header and footer models exist in storage, returning UITableView.automaticDimension for sections, whose header and footer models are Strings (for table section titles), as well as returning minimal height for cases where data model is not there(which happens to be different for UITableView.Style.plain and UITableView.Style.grouped). Those properties default to true, but if you want to use self-sizing table view sections headers or footers, which may improve perfomance, consider turning those off:
    manager.configuration.semanticHeaderHeight = false
    manager.configuration.semanticFooterHeight = false
    

    Please note, that even when those properties are set to false, corresponding UITableViewDelegate methods will still be called in two cases:

    1. Your DTTableViewManageable instance implements them
    2. You register a heightForHeader(withItem:_:) or heightForFooter(withItem:_:) closures on DTTableViewManager instance.

    Breaking

    This release requires Swift 5.3. Minimum iOS / tvOS deployment targets are unchanged (iOS 11, tvOS 11).

    Some context: this release heavily relies on where clauses on contextually generic declarations, that are only available in Swift 5.3 - SE-0267.

    • ViewModelMapping is now a generic class, that captures view and model information(ViewModelMapping<T,U>).

    Fixed

    • indentationLevelForCell closure now correctly returns Int instead of CGFloat.
    • Several event API's have been improved to allow returning nil for methods, that accept nil as a valid value: contextMenuConfiguration, previewForHighlightingContextMenu, previewForDismissingContextMenu.

    Changed

    • Generic placeholders for cell/model/view methods have been improved for better readability.

    Deprecated

    • Several cell/header/footer/supplementary view registration methods have been deprecated to unify registration logic. Please use register(_:mapping:handler:), registerHeader(_:mapping:handler:), registerFooter(_:mapping:handler:) as a replacements for all of those methods. For more information on those changes, please read migration guide.
    • All non-deprecated registration methods now have an additional handler closure, that allows to configure cells/headers/footers that are dequeued from UITableView. This is a direct replacement for configure(_:_:, configureHeader(_:_:), configureFooter(_:_:) , that are all now deprecated. Please note, that handler closure is called before DTModelTransfer.update(with:) method.
    • DTTableViewManager.configureEvents(for:_:), it's functionality has become unnecessary since mapping closure of cell/header/footer registration now captures both cell and model type information for such events.
    • DTTableViewManager.configureDiffableDataSource(modelProvider:) for non-hashable data models. Please use configureDiffableDataSource method for models, that are Hashable. From Apple's documentation: If you’re working in a Swift codebase, always use UITableViewDiffableDataSource instead.
    • TableViewUpdater.usesLegacyTableViewUpdateMethods property.
    Source code(tar.gz)
    Source code(zip)
  • 7.1.0(Apr 29, 2020)

    Changed

    • It's not longer necessary to import DTModelStorage framework to use it's API's. import DTTableViewManager now implicitly exports DTModelStorage.
    Source code(tar.gz)
    Source code(zip)
  • 7.0.0(Nov 8, 2019)

  • 7.0.0-beta.2(Sep 6, 2019)

  • 7.0.0-beta.1(Aug 20, 2019)

    This is a major release with some breaking changes, please read DTTableViewManager 7.0 Migration Guide

    Added

    • configureDiffableDataSource(modelProvider:) method to enable UITableViewDiffableDataSource with DTTableViewManager.
    • Ability for DTTableViewManageable to implement tableView(_:viewForHeaderInSection:) and tableView(_:viewForFooterInSection:) to return view directly without going through storages.
    • minimalHeaderHeightForTableView and minimalFooterHeightForTableView properties for TableViewConfiguration, that allows configuring height for section headers and footers that need to be hidden.
    • Ability to customize bundle, from which xib files are loaded from by setting bundle property on ViewModelMapping in mappingBlock. As before, bundle defaults to Bundle(for: ViewClass.self).
    • DTTableViewManager.supplementaryStorage getter, that conditionally casts current storage to SupplementaryStorage protocol.

    New method wrappers for iOS 13 API

    • shouldBeginMultipleSelectionInteraction
    • didBeginMultipleSelectionInteraction
    • didEndMultipleSelectionInteraction
    • contextMenuConfiguration(for:)
    • previewForHighlightingContextMenu
    • previewForDismissingContextMenu
    • willCommitMenuWithAnimator

    Changed

    • If tableView section does not contain any items, and TableViewConfiguration.display<Header/Footer>OnEmptySection property is set to false, DTTableViewManager no longer asks for header footer height explicitly and returns TableViewConfiguration.minimal<Header/Footer>HeightForTableView.
    • Anomaly event verification now allows subclasses to prevent false-positives.
    • animateChangesOffScreen property on TableViewUpdater that allows to turn off animated updates for UITableView when it is not on screen.

    Removed

    • Usage of previously deprecated and now removed from DTModelStorage ViewModelMappingCustomizing protocol.

    Breaking

    DTModelStorage header, footer and supplementary model handling has been largely restructured to be a single closure-based API. Read more about changes in DTModelStorage changelog. As a result of those changes, several breaking changes in DTTableViewManager include:

    • SupplementaryAccessible extension with tableHeaderModel and tableFooterModel properties has been removed.
    • Because headers/footers are now a closure based API, setSectionHeaderModels and setSectionFooterModels do not create sections by default, and do not call tableView.reloadData.
    • If a storage does not contain any sections, even if configuration.displayHeaderOnEmptySections or configuration.displayFooterOnEmptySections is set, headers and footers will not be displayed, since there are no sections, which is different from present sections, that contain 0 items. For example, If you need to show a header or footer in empty section using MemoryStorage, you can call memoryStorage.setItems([Int](), forSectionAt: emptySectionIndex), and now with empty section header and footer can be displayed.

    Other breaking changes:

    • tableViewUpdater will contain nil if DTTableViewManager is configured to work with UITableViewDiffableDataSource.
    • DTTableViewOptionalManageable protocol was removed and replaced by optionalTableView property on DTTableViewManageable protocol. One of tableView/optionalTableView properties must be implemented by DTTableViewManageable instance to work with DTTableViewManager.

    Deprecated

    Following methods have been deprecated due to their delegate methods being deprecated in iOS 13:

    • editActions(for:)
    • shouldShowMenuForItemAt
    • canPerformAction
    • performAction
    Source code(tar.gz)
    Source code(zip)
    DTTableViewManager.framework.zip(13.63 MB)
  • 6.6.0(Jun 17, 2019)

  • 6.5.0(Apr 7, 2019)

  • 6.4.0(Sep 25, 2018)

  • 6.3.0(Jun 9, 2018)

    Added

    • Anomaly detecting system for various errors in DTTableViewManager. Read more about it in Anomaly Handler Readme section. Anomaly handler system requires Swift 4.1 and higher.
    • Support for Swift 4.2 in Xcode 10 beta 1.

    Changed

    • Calling startManaging(withDelegate:_) method is no longer required.

    Breaking

    • viewFactoryErrorHandler deprecated property on DTTableViewManager was removed. All previously reported errors and warnings are now a part of anomaly detecting system.
    Source code(tar.gz)
    Source code(zip)
    DTTableViewManager.framework.zip(7.00 MB)
  • 6.2.0(May 3, 2018)

    Breaking

    • editingStyle(for:_,_:) method was replaced with editingStyle(forItem:_,:_) method, that accepts model and indexPath closure, without cell. Reason for that is that UITableView may call this method when cell is not actually on screen, in which case this event would not fire, and current editingStyle of the cell would be lost.
    Source code(tar.gz)
    Source code(zip)
    DTTableViewManager.framework.zip(6.32 MB)
  • 6.1.1(Apr 2, 2018)

  • 6.1.0-beta.1(Dec 4, 2017)

    • Implemented new system for deferring datasource updates until performBatchUpdates block. This system is intended to fight crash, that might happen when performBatchUpdates method is called after UITableView.reloadData method(for example after calling memoryStorage.setItems, and then immediately memoryStorage.addItems). This issue is detailed in https://github.com/DenHeadless/DTCollectionViewManager/issues/27 and https://github.com/DenHeadless/DTCollectionViewManager/issues/23. This crash can also happen, if iOS 11 API UITableView.performBatchUpdates is used. This system is turned on by default. If, for some reason, you want to disable it and have old behavior, call:
    manager.memoryStorage.defersDatasourceUpdates = false
    
    • TableViewUpdater now uses iOS 11 performBatchUpdates API, if this API is available. This API will work properly on MemoryStorage only if defersDatasourceUpdates is set to true - which is default. However, if for some reason you need to use legacy methods beginUpdates, endUpdates, you can enable them like so:
    manager.tableViewUpdater?.usesLegacyTableViewUpdateMethods = true
    

    Please note, though, that new default behavior is recommended, because it is more stable and works the same on both UITableView and UICollectionView.

    • tableViewUpdater property on DTTableViewManager is now of TableViewUpdater type instead of opaque StorageUpdating type. This should ease use of this object and prevent type unneccessary type casts.
    Source code(tar.gz)
    Source code(zip)
    DTTableViewManager.framework.zip(5.50 MB)
  • 6.0.0(Nov 1, 2017)

  • 6.0.0-beta.3(Oct 5, 2017)

  • 6.0.0-beta.2(Sep 27, 2017)

  • 6.0.0-beta.1(Sep 10, 2017)

    This is a major release with some breaking changes, please read DTTableViewManager 6.0 Migration Guide

    • Added updateVisibleCells(_:) method, that allows updating cell data for visible cells with callback on each cell. This is more efficient than calling reloadData when number of elements in UITableView does not change, and only contents of items change.
    • Implement configureEvents(for:_:) method, that allows batching in several cell events to avoid using T.ModelType for events, that do not have cell created.
    • Added event for UITableViewDelegate tableView(_:targetIndexPathForMoveFromRowAt:toProposedIndexPath:
    • Added events for focus engine on iOS 9
    • Added events for iOS 11 UITableViewDelegate methods: tableView(_:leadingSwipeActionsConfigurationForRowAt:, tableView(_:trailingSwipeActionsConfigurationForRowAt:, tableView(_:shouldSpringLoadRowAt:withContext:
    • UITableViewDelegate and UITableViewDatasource implementations have been refactored from DTTableViewManager to DTTableViewDelegate and DTTableViewDataSource classes.
    • DTTableViewManager now allows registering mappings for specific sections, or mappings with any custom condition.
    • Added move(_:_:) method to allow setting up events, reacting to tableView:moveRowAt:to: method.

    Breaking

    • Signature of move(_:_:) method has been changed to make it consistent with other events. Arguments received in closure are now: (destinationIndexPath: IndexPath, cell: T, model: T.ModelType, sourceIndexPath: IndexPath)
    • tableView(UITableView, moveRowAt: IndexPath, to: IndexPath) no longer automatically moves items, if current storage is MemoryStorage. Please use MemoryStorage convenience method moveItemWithoutAnimation(from:to:) to move items manually.

    Deprecated

    • Error handling system of DTTableViewManager is deprecated and can be removed or replaced in future versions of the framework.
    Source code(tar.gz)
    Source code(zip)
    DTTableViewManager.framework.zip(5.88 MB)
  • 5.3.0(Apr 6, 2017)

    • Use new events system from DTModelStorage, that allows events to be properly called for cells, that are created using ViewModelMappingCustomizing protocol.
    Source code(tar.gz)
    Source code(zip)
  • 5.2.0(Jan 29, 2017)

    New

    • Setting TableViewUpdater instance to tableViewUpdater property on DTTableViewManager now triggers didUpdateContent closure on TableViewUpdater.
    • Added sectionIndexTitles event to replace UITableViewDataSource.sectionIndexTitles(for:) method.
    • Added sectionForSectionIndexTitle event to replace UITableViewDataSource.tableView(_:sectionForSectionIndexTitle:at) method.

    Bugfixes

    • All events that return Optional value now accept nil as a valid event result.
    • didDeselect(_:,_:) method now accepts closure without return type - since UITableViewDelegate does not have return type in that method.
    Source code(tar.gz)
    Source code(zip)
  • 5.1.0(Oct 28, 2016)

    Dependency changelog -> DTModelStorage 4.0.0 and higher

    • TableViewUpdater has been rewritten to use new StorageUpdate properties that track changes in order of their occurence.
    • TableViewUpdater reloadRowClosure and DTTableViewManager updateCellClosure now accept indexPath and model instead of just indexPath. This is done because update may happen after insertions and deletions and object that needs to be updated may exist on different indexPath.
    Source code(tar.gz)
    Source code(zip)
  • 5.0.0(Oct 23, 2016)

  • 5.0.0-beta.3(Oct 13, 2016)

    • DTModelStorage dependency now requires Realm 2.0
    • UITableViewDelegate heightForHeaderInSection and heightForFooterInSection are now properly called on the delegate, if it implements it(thanks, @augmentedworks!).
    Source code(tar.gz)
    Source code(zip)
  • 5.0.0-beta.2(Sep 28, 2016)

    Added

    • DTTableViewOptionalManageable protocol, that is identical to DTTableViewManageable, but allows optional tableView property instead of implicitly unwrapped one.
    • Enabled RealmStorage from DTModelStorage dependency
    Source code(tar.gz)
    Source code(zip)
Owner
Denys Telezhkin
Denys Telezhkin
A PageView, which supporting scrolling to transition between a UIView and a UITableView

YXTPageView ##A Page View, which support scrolling to transition between a UIView and a UITableView UIView (at the top) UITableView (at the bottom) In

Hanton Yang 68 May 25, 2022
Simple and beautiful stacked UIView to use as a replacement for an UITableView, UIImageView or as a menu

VBPiledView simple but highly effective animation and interactivity! By v-braun - viktor-braun.de. Preview Description Very simple and beautiful stack

Viktor Braun 168 Jan 3, 2023
Easy UITableView drag-and-drop cell reordering

SwiftReorder NOTE: Some users have encountered compatibility issues when using this library with recent versions of iOS. For apps targeting iOS 11 and

Adam Shin 378 Dec 13, 2022
A cells of UITableView can be rearranged by drag and drop.

TableViewDragger This is a demo that uses a TableViewDragger. Appetize's Demo Requirements Swift 4.2 iOS 8.0 or later How to Install TableViewDragger

Kyohei Ito 515 Dec 28, 2022
INTUZ is presenting an interesting a Multilevel Expand/Collapse UITableView App Control to integrate inside your native iOS-based application

INTUZ is presenting an interesting a Multilevel Expand/Collapse UITableView App Control to integrate inside your native iOS-based application. MultilevelTableView is a simple component, which lets you use the tableview with multilevel tree view in your project.

INTUZ 3 Oct 3, 2022
A declarative api for working with UITableView.

⚡️ Lightning Table Lightning Table provides a powerful declarative API for working with UITableView's. Table views are the foundation of almost every

Electric Kangaroo 28 Aug 25, 2021
A simple way to create a UITableView for settings in Swift.

QuickTableViewController A simple way to create a table view for settings, including: Table view cells with UISwitch Table view cells with center alig

Cheng-Yao Lin 525 Dec 20, 2022
A pixel perfect replacement for UITableView section index, written in Swift

MYTableViewIndex MYTableViewIndex is a re-implementation of UITableView section index. This control is usually seen in apps displaying contacts, track

Yury 520 Oct 27, 2022
A subclass of UITableView that styles it like Settings.app on iPad

TORoundedTableView As of iOS 13, Apple has released an official version of this table view style called UITableViewStyleInsetGrouped! Yay! In order to

Tim Oliver 162 Nov 2, 2022
A simpler way to do cool UITableView animations! (╯°□°)╯︵ ┻━┻

TableFlip (╯°□°)╯︵ ┻━┻ ┬──┬ ノ( ゜-゜ノ) Animations are cool. UITableView isn't. So why not make animating UITableView cool? The entire API for TableFlip

Joe Fabisevich 555 Dec 9, 2022
A UITableView extension that enables cell insertion from the bottom of a table view.

ReverseExtension UITableView extension that enabled to insert cell from bottom of tableView. Concept It is difficult to fill a tableview content from

Taiki Suzuki 1.7k Dec 15, 2022
Simple single-selection or multiple-selection checklist, based on UITableView

SelectionList Simple single-selection or multiple-selection checklist, based on UITableView. Usage let selectionList = SelectionList() selectionList.i

Yonat Sharon 111 Oct 6, 2022
A declarative wrapper approach to UITableView

Thunder Table Thunder Table is a useful framework which enables quick and easy creation of table views in iOS, making the process of creating complex

3 SIDED CUBE 20 Aug 25, 2022
MultiplyTypeCellExample - An example of the implementation of different types of cells in a tableview

MultiplyTypeCellExample An example of the implementation of different types of c

Marina Demchenko 0 Feb 13, 2022
ClassicPhotos is a TableView App demos how to optimize image download and filter with operation queue.

ClassicPhotos ClassicPhotos is a TableView App demos how to optimize image download and filter with operation queue. With Operation and Operation Queu

Kushal Shingote 2 Dec 18, 2021
Display list of Marvel comic Characters and its detail view

Marvel Universe Display list of Marvel comic Characters and its detail view Installation Dependencies in this project are provided via Xcodegen (proje

null 1 Oct 19, 2021
APDynamicGrid is a SwiftUI package that helps you create consistent and animatable grids.

APDynamicGrid Overview APDynamicGrid is a SwiftUI package that helps you create consistent and animatable grids. The DynamicGrid View preserves the sa

Antonio Pantaleo 29 Jul 4, 2022
Use Yelp API to fetch restuarants around a location and show them in a table view

Yelp Use Yelp API to fetch restuarants around a location and show them in a table view - Infinite scrolling, Prefetching, Image Caching. Design Patter

null 0 Nov 1, 2021