DTTableViewManager Versions Save

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

11.0.0

1 year ago

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.

11.0.0-beta.1

1 year ago

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.

10.0.0

2 years ago

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.

9.0.0-beta.1

2 years ago

8.0.1

3 years ago

Added

  • Support for DTModelStorage 9.1

8.0.0

3 years ago

8.0.0-beta.1

3 years ago

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.

7.2.0

3 years ago

7.1.0

4 years ago

Changed

  • It's not longer necessary to import DTModelStorage framework to use it's API's. import DTTableViewManager now implicitly exports DTModelStorage.

7.0.0

4 years ago
  • willCommitMenuWithAnimator method has been made unavailable for Xcode 11.2, because UITableViewDelegate method it used has been removed from UIKit on Xcode 11.2.