dentelezhkin / dttableviewmanager Goto Github PK
View Code? Open in Web Editor NEWProtocol-oriented UITableView management, powered by generics and associated types.
License: MIT License
Protocol-oriented UITableView management, powered by generics and associated types.
License: MIT License
After 6.1.0 release it doesn't updates after use updateWithoutAnimations
block and call reloadData()
. Same for the DTCollectionView
. Check this please.
You and I used 'Food' as a demo table view model item. Great minds think alike :D
https://github.com/rob-nash/CollapsibleTable
i found you via https://github.com/uhub/awesome-swift
happy coding !
Hi! Thanks for great lib!
I have issue with swift 4 and cocoa pods installation
[!] Unable to satisfy the following requirements:
DTTableViewManager (~> 6.0)
required by Podfile
None of your spec sources contain a spec satisfying the dependency: DTTableViewManager (~> 6.0)
.
You have either:
pod repo update
or with pod install --repo-update
.Note: as of CocoaPods 1.0, pod repo update
does not happen on pod install
by default.
I just recently tried to integrate this to my project and this project didn't build correctly when integrating via Carthage. So I forked it and after opening the project I could see that it was lacking the correct inclusion of Carthage dependencies using the suggested build script phase method. This was also true for the DTModelStorage dependency which I explain in this issue.
I'm working on a project where I actually use Protocols to represent my model objects rather than classes. The main reason is that I use Parse subclasses to manage my data, and yet I do not want my View layer classes to know about Parse subclasses. Thus, Views talk to Model protocols (e.g. Recipe
protocol describes a recipe, whereas a MESRecipe_Parse
PFObject
subclass conforms to it).
I tried it, it doesn't look like DTTableViewController
supports this because it fails to find the cell mapping.
class RecipeSearchResultCell: UITableViewCell, ModelTransfer {
func updateWithModel(model: MESRecipe_Parse) {
NSLog("Calling update with model.")
}
}
What to do?
With iOS 10.2 I see an issue with a delay on loading the table cells and also sometimes displaying the text and image I have in the cell don't load correctly either (usually occurs on one cell and the other cells display fine). Works fine on previous iOS versions. I've tried storageNeedsReloading() and reloadItem(item) to force a reload but to no avail.
It doesn't generate a working example project.
How am I supposed to specify a cell height when using DTTableViewManager? I tried by adding my view controller as a UITableViewDelegate
but then things like the cellSelection
method callback didn't work any more as they seem to rely on delegation.
I guess that either there is not yet a possibility to do this or the README is lacking information that points out the correct direction. I might have missed it, of course, too. Could you clarify? Thanks for your help!
Hello, Den! Thanks for your library.
When I'm trying to add and update CoreData Item in single transaction, NSFetchedResultsController is break down. App not crashing, but data in tableview is incorrect, and no ways to reload, or update.
Create custom header views in the same manner as creating cells with factory and models.
Thanks to @ksalak for this one. That is a a good addition, i will work on it as soon as i have time.
How update cell, without hidden keyboard?
In my project, I have custom cell in a xib file, but I am using it in a TableView in Storyboard. It's like your StoryboardController in Example project, but putting the cell in a nib, rather than in the Storyboard.
When I run the project I get blank cells . But if I use TableView in a xib file, everything just works fine.
Hello!
If you add a new item on your memoryStorage within a whenSelected function, configureCell for the new cell doesn't get called.
For example:
manager.registerCellClass(RightDetailTableViewCell.self) { [weak self] (cell, model, indexPath) -> Void in let someObject = SomeObject() try! manager.memoryStorage.addItem(someObject, toSection: 0) }
manager.configureCell(SomeCell.self) { (cell, model, indexPath) -> Void in print("This doesn't get called") }
I discovered that calling performSelectorOnMainThread works, which is strange because what is inside the whenSelected function is already executed on the main thread.
manager.registerCellClass(RightDetailTableViewCell.self) { [weak self] (cell, model, indexPath) -> Void in self?.performSelectorOnMainThread("addItem", withObject: userInfo, waitUntilDone: true) }
func addItem() { let someObject = SomeObject() try! manager.memoryStorage.addItem(someObject, toSection: 0) }
Thanks
I have model object which I wish to display a different group of cells depending on the state of the object.
Something like the following:
[self registerCellClass:[FirstCell class]
forModelClass:[CustomModel class]];
[self registerCellClass:[SecondCell class]
forModelClass:[CustomModel class]];
[self registerCellClass:[Relationship class]
forModelClass:[CustomModel class]];
[[self memoryStorage] addItem:object];
if (object.numberOfFriends > 0) {
for (NSInteger idx = 0; i < object.numberOfFriends; idx ++ ) {
[[self memoryStorage] addItem:object.friends[idx]];
}
}
As issue posted under DTModelStorage. Here is the cartfile portion:
github "DenHeadless/DTTableViewManager" ~> 4.7.0
github "realm/realm-cocoa"
How can I invoke in cell custom action? For example I have viewController with
func presentScreen() { let viewController = ViewController() present(viewController, animated: true, completion: nil) }
and want to call this method on tap a button from cell
class RecipeSearchResultsViewController: UITableViewController, DTTableViewManageable {
override func viewDidLoad() {
super.viewDidLoad()
manager.startManagingWithDelegate(self)
manager.registerCellClass(RecipeSearchResultCell) // error occurs here.
}
}
Hey guys!
I have some troubles with tableView header width only on devices iPhone 6+, 6s+ with iOS 9x.
The header is a UITableViewHeaderFooterView.
The table view's style was set as "Grouped".
Hi,
In example Add/remove/select, after removing, and adding some rows I got this result:
Rows numbers are repeated.
I don't now it's error in this example or in the framework.
Keep good work. Regards.
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. :)
Hello! Good Job, I like your repo. But I have a question :)
I have cell with UITextField and configure, it with default text. TextField from cell after editing change stored property in View Controller. When I scroll tableView down and up again textfield text setting to default textFieldText
value. How to listen changes of textFieldText
?
// stored property
var textFieldText = "TextField"
override func viewDidLoad() {
super.viewDidLoad()
// .. configurate manager
manager.memoryStorage.addItem(textFieldText)
}
// cell
func update(with model: String) {
textField.text = model
}
Can not make it work with iOS 8 SDK. Headers are permanently hidden by zero size. This line helps:
self.tableView.sectionHeaderHeight = 20;
How I register Header:
[self registerHeaderClass:[TRHeaderView class] forModelClass:[NSString class]];
If the define a ABCTableViewCell, the runtime class name may change to TC9ABCTableViewCell, so the nib file check code will not work.
This code gives me constant crash:
[self.memoryStorage updateWithoutAnimations:^{
[self.memoryStorage addItems:items];
[self.memoryStorage setSectionFooterModels:@[[DTDefaultHeaderFooterModel modelWithReuseIdentifier:@""
configurationBlock:^(UITableViewHeaderFooterView *view) {
NSString *string = [NSString stringWithFormat:@"%@ %@",
NSLocalizedString(@"settings.aboutTitle", nil),
[NSString stringWithFormat:@"%@ ver. %@", name, version]];
view.textLabel.text = string;
}]]];
}];
[self.tableView reloadData];
Console output:
-[DTDefaultHeaderFooterModel length:]: unrecognized selector sent to instance 0x7aec86c0
how i can override this func ?
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
i need this to reorder items in database
Rename 'DTTableViewManager' to 'DTTableViewController' because it's a subclass of 'UIViewController' and should follow naming conventions
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.
Yep, the question is: what is the best way to add filtering using DTTableViewManager
?
Thanks in advance.
Yo.
I'm trying to fill a DTTableViewController with contacts which i grabbed from ABAddressBook and I get this error :
Assertion failure in -[DTTableViewFactory cellReuseIdentifierForModel:], /.........../DTTableViewFactory.m:212
2014-12-12 12:38:23.118 project[34878:950622] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'DTCellFactory does not have cell mapping for model class: __NSCFType'
Here's my code:
var adbk : ABAddressBook!
var errorRef: Unmanaged<CFError>?
adbk = self.extractABAddressBookRef(ABAddressBookCreateWithOptions(nil, &errorRef))
var contactList: NSArray = ABAddressBookCopyArrayOfAllPeople(adbk).takeRetainedValue()
println("records in the array \(contactList.count)")
for record:ABRecordRef in contactList {
var contactPerson: ABRecordRef = record
var contactName: String = ABRecordCopyCompositeName(contactPerson).takeRetainedValue() as NSString
println ("contactName \(contactName)")
}
self.memoryStorage().removeAllTableItems() //Working until here
self.memoryStorage().addItems(contactList) // This brings the error
Current implementation does not allow to register UITableView
header to UITableViewCell
prototyped in storyboard. But it's a useful hint. Described here: http://stackoverflow.com/a/32261262/1469060
Trying to implement reactive extension for DTTableViewManager
, like this:
extension DTTableViewManager {
func rx_modelSelected<T:ModelTransfer where T:UICollectionViewCell>(cellClass: T.Type) -> Observable<(T, T.ModelType, NSIndexPath)>{
Observable<(T, T.ModelType, NSIndexPath)>.create { [weak self] (observer) -> Disposable in
self?.whenSelected(cellClass) { cell, model, indexPath -> Void in
observer.onNext((cell, model, indexPath))
}
}
}
}
But whenSelected
gives an error:
Value of type 'DTTableViewManager' has no member 'ModelType'
I'm not very familiar with typealias
. How to make this 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)
}
}
Hello Den,
there's a problem with the RealmStorage setSection function when the realm database is read only.
You get an exception when adding the notification block to the results because 'Read-only Realms do not change and do not have change notifications'.
We should check that before adding the notification block. Something like that:
open func setSection<T:Object>(with results: Results<T>, forSection index: Int) {
guard index <= sections.count else { return }
let section = RealmSection(results: results)
notificationTokens[index]?.stop()
notificationTokens[index] = nil
if index == sections.count {
sections.append(section)
} else {
sections[index] = section
}
if results.realm?.configuration.readOnly == false {
let sectionIndex = sections.count - 1
notificationTokens[index] = results.addNotificationBlock({ [weak self] change in
self?.handleChange(change, inSection: sectionIndex)
})
}
delegate?.storageNeedsReloading()
}
Please let me know if you want me to submit a pull request.
Thanks! 🍻🍻
Davide
Edit: sorry, I should have put it in DTModelStorage.
When using method -addTableItems with any number of items greater than 1, tableView always using animation UITableViewRowAnimationAutomatic. It should use UITableViewRowAnimationNone.
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?
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.
Checking out a fresh project is missing DTModelTransfer
classes and other files.
Is [DTMemoryStorage removeAllTableItems]
animated?
In my case items get removed without animation. The similar code works correct:
[self.memoryStorage removeItems:[[self.memoryStorage.sections[0] objects] copy]];
I have attempted to use the updater class including trying the setup from the tests but it never seems to be called. I have also tried to create my own and register it but it is the same result. Never seems to get called. Does anyone have working example code of this in action?
EDIT: It does "work" but doesn't fire if the table has 0 content to be updated. I.E empty state as a result of no content that could be loaded. I think readme is incorrect
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.
Normally you conform to UITableViewDataSource and you can add the function like:
sectionForSectionIndexTitle and sectionIndexTitlesForTableview.
However conforming to the UITableViewDataSource results in having to add all the functions like cellForRow and numberOfSections etc which break the manager acting as datasource/manager. How can I can i still call the manager to display the indexTitles?
I am using CoreData with a fetchResultController and have a keyPath (firstLetter) to assign to each sectionHeader.
Hi,
First of all this is a great component and thanks for making this repo getting continued support.
My question,
How to make a cell reuse only for specific indexpath? This because i want specific cells to not get reused in static screen(not a list based screen).
For Eg: I am having a textfield cell in which i have a textfield. But when it get scrolled and reused the new textfield shows the old input in the field
Another example:
I have a tableview cell with horizontal collection view inside it.
If the first tableview cell's horizontal collectionView is scrolled to end. Then the user scrolls the tableview to the end and a new horizontal collection view cell comes. The horizontal cell which shows
up is scrolled to the end. But conceptually it shouldn't scroll.
The solution would be to reuse the cell only for that specific indexpath.
Would really appreciate if you can guide me on this problem.
Thanks in advance.
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
After updating my pods, I've found that displayHeaderOnEmptySection no longer exists. Is there any alternative to not show headers in empty section?
Subclass DTTableViewController, create xib, or storyboard with your view controller, wire up tableView outlet.
Is it possible to implement table view controller without xib or storyboard using this project?
Sorry, this is not a bug or issue, just looking for some guidance.
There's a really good post out there detailing how to put collection-views inside of UITableViewCells.
https://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell-in-swift/
I'm trying to do something similar to this, but using DTTableViewManager (to populate UITableViewCells) and DTCollectionViewManager (for the UICollectionView that shows up inside each UITableViewCell)
My data model looks something like this:
// The number of cells in the main tableview = allDecks.count - DTTableViewManager's data source
var allDecks: [Deck]
// each UICollectionView represents a single Deck.
struct Deck {
var cards: [Card]
}
// each cell in a UICollectionView draws a single Card
struct Card {
var suit: Int
var value: Int
}
Of course, the real data looks a little different. I'm using Realm for DTModelStorage, for example.
I'm just wondering if you've attempted anything like this using DTTableViewManager and DTCollectionViewManager, and might offer some advice on how best to proceed?
I'm working on a solution right now - but haven't cracked it yet. Any advice would be welcome.
The function is declared as:
public func addItems<T>(items: [T], toSection index: Int = 0)
So we're unable to pass array of different models. They all have to be the same class. Probably the function might be declared as:
public func addItems(items: [AnyObject], toSection index: Int = 0)
It always logs DTMemoryStorage: item to delete was not found at indexPath:
Because you kinda mutating while enumerating:
for (NSIndexPath * indexPath in indexPaths)
{
id object = [self objectAtIndexPath:indexPath];
if (object)
{
DTSectionModel * section = [self getValidSection:indexPath.section];
[section.objects removeObjectAtIndex:indexPath.row];
[self.currentUpdate.deletedRowIndexPaths addObject:indexPath];
}
else
{
if (self.loggingEnabled)
{
NSLog(@"DTMemoryStorage: item to delete was not found at indexPath : %@ ", indexPath);
}
}
}
Example:
I want to remove (0-1) and (0-2).
Remove (0-1) - okay
objectAtIndexPath:(0-2) returns nil.
You should shift index paths or sort 'em and start from the end.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.