Why is tableView:canMoveRowAtIndexPath: in the UITableViewDataSource protocol? - ios

Why is tableView:canMoveRowAtIndexPath: is UITableViewDataSource protocol and not in UITableViewDelegate protocol?
Similar methods (e.g. tableView:canFocusRowAtIndexPath:) are in Delegate protocol. I don't think it's a mistake, so can anyone explain why such method is part of the data source and not the delegate?
A general explanation of which methods belong to data source protocols and which belong to delegate protocols is also appreciated.

The delegate methods generally have to do with the appearance of the table view.
The data source methods generally have to do with the content of the table view. It's often the case that the displayed content's order is fixed. Say the table view was displaying stops on a bus line, or the chapter headings of a book. You can't let the user reorder those: it isn't something that the content itself supports.
Notice that both delegate and data source are actually involved in the decision as to whether a row can move. The data source gets the method you named, but the delegate gets asked tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: at the same time.

The UITableViewDatasource protocol documentation:
The UITableViewDataSource protocol is adopted by an object that
mediates the application’s data model for a UITableView object. The
data source provides the table-view object with the information it
needs to construct and modify a table view.
As a representative of the data model, the data source supplies
minimal information about the table view’s appearance. The table-view
object’s delegate—an object adopting the UITableViewDelegate
protocol—provides that information.
The required methods of the protocol provide the cells to be displayed
by the table-view as well as inform the UITableView object about the
number of sections and the number of rows in each section. The data
source may implement optional methods to configure various aspects of
the table view and to insert, delete, and reorder rows.
Hope, that clears things out.
EDIT: With my own words (but repeating the docs): Datasource declares methods those somehow directly or indirectly affect/reflect the data model, whereas the method tableView:canFocusRowAtIndexPath: can't be said similar to tableView:canMoveRowAtIndexPath: because it has nothing to do with the data. That said, datasource carries constructive character, delegate - informative.

Related

In iOS, is the UITableViewDataSource considered the program's logic?

I'm following a UITableView tutorial and I've learned that the UITableView is a view object which doesn't handle the logic or data, it primarily the view or user interface. As I continued reading it says that the UITableView requires a "datasource". My question is this, is the datasource the program's logic?
IOS app development widely use Delegate design pattern. Almost all UIView have their own Delegate Protocol. Before understand UITableViewDelegate and UITableViewDatasource Protocol try to learn about Delegate design pattern.
If you work with UITableView you have to implement atleast 2 protocol in your ViewController.
1. UITableViewDelegate : The delegate of a UITableView object must adopt the UITableViewDelegate protocol. Optional methods of the protocol allow the delegate to manage selections, configure section headings and footers, help to delete and reorder cells, and perform other actions.
2. UITableViewDataSource: The UITableViewDataSource protocol is adopted by an object that mediates the application’s data model for a UITableView object. The data source provides the table-view object with the information it needs to construct and modify a table view.

Why height related methods are placed in UITableViewDelegate, not in UITableViewDataSource

I found a question in a quiz is "Which UIKit protocol contains the method –tableView:heightForRowAtIndexPath:?"
without taking any load the protocol comes in my mind was UITableViewDataSource. But when I checked apple developer documentation, I found I was wrong. UITableViewDelegate is the protocol who contain that method.
Before that I understood was that these height methods are part of Datasource protocol.
Is there any specific reason of placing them in UITableViewDelegate instead of UITableViewDataSource ?
Why following function are placed in UITableViewDelegate
heightForRowAt indexPath
heightForHeaderInSection
heightForFooterInSection
and Why following function are placed in UITableViewDataSource
numberOfSectionsInTableView
numberOfRowsInSection
Before now I thought these are similar type of function so these methods must be placed in same protocol.
Please make this clear to me.
Thanks in advance
UITableViewDelegate means you provide answers to requests about the layout of the table and about actions the user performs on the tableview.
UITableViewDatasource means you provide data for the sections and rows of a table and you act on messages that change a table's data.
For more in details, Check DataSource and Delegate
numberOfSectionsInTableView and numberOfRowsInSection are functions that answer questions about the data to be displayed which is why they are to be found in the DataSource protocol.
The heightFor... functions don’t answer anything about the underlying data but only on the way the data is displayed. This is why they are part of the Delegate protocol.
Does that make sense to you?
The datasource supplies the data, the delegate supplies the behavior.
In MVC, datasource is in the model layer and the delegate is in the control layer.
Actually, on second thought, the datasource is usually controller that is lower down, closer to the model. I don't think I've ever used a model object as my datasource.
The UI prospects of the UITableView are provided by the UITableViewDelgate methods and the data (we are not talking about the data to be used inside the cell, just the information about UI (section, row, etc.) repetitions) needed to construct the UI is provided by UITableViewDataSource methods.

Working principle of delegate and datasource

Just want to know the working priciple of iOS delegate and datasource.
For example, when I call a [tableView numberOfRowsInSection] in some ViewController.
Seems that it is returning me [tableView.dataSource numberOfRowsInSection]
But how can I invoke [tableView numberOfRowsInSection] without returning [tableView.dataSource numberOfRowsInSection]?
May I know what is happening behind the code? Thank in advance.
In iOS, delegate and dataource are implemented as delegation pattern. The different between them is about it's responsible and relationship with the delegating object. delegate is control of user interface, while data source is control of data. They all have to adopt protocol, in which defines a set of methods that act relevantly with each others.
Table View delegate and data source implemented aim to adopt one of best practice of using delegation pattern. Delegation design pattern responds sometimes as a callback function, however, in the case of table view data source and delegate, it allows you to control and customize properties and behavior of table view.
An example of that you can see is that implementing delegate and data source allows you to customize your table view properties such as number or sections, number of rows, which type of cells and it's behavior like clicks a row.

Does it ever make sense to split UITableDelegate and UITableDataSource?

This has bugged me for a long time. There are two delegate protocols defined for UITableView: the actual delegate and the data source. However, given the way the methods are distributed between the two, I'm yet to see a situation when it is practical to implement the protocols in two separate objects. Could anyone give me an example when it actually makes sense to do so?
Short answer: Yes it does.
Long answer:
They are split in 2 different protocols, because they serve different purposes.
The delegate is responsible for managing aspects of the table itself like selection, reordering and deletion of rows, ... UITableViewDelegate Protocol Reference
In contrast to that UITableViewDatasource is responsible for adapting your data model so that it fits the needs of the table. It provides the cells for the table, tells the table how many sections there are, how many rows per section there are, ... UITableViewDatasource Protocol Reference
Depending on your data and what you want to do with the table, that code can become arbitrarily large. If it's getting too large, you can split it up for better navigation and overview. That would be one case I can think of where this distinction can improve code quality.
IMO you don't get any benefits by doing so, as the datasource just provides methods to interact with data, same as the delegate. If your store is big and clumsy, separating the datasource won't solve the issue.
No added value
You can get some unpredictable behavior when forcing the separation:
UITableView issue when using separate delegate/dataSource
How to avoid big and clumsy UITableViewController on iOS?
It depends on the specifics of the app
On the other hand, depending on the app design it may be required to separate the datasource from the delegate:
Lighter View Controllers
UITableView delegate and datasource in a separate class after parsing

Best way to implement UICollectionViewDataSource protocol?

I have theoretical question.
Currently my app is using UICollectionView as a way to display objects list. UIViewController, that contains UICollectionView as subview, implements UICollectionViewDelegate protocol and acts as delegate and datasource. Datasource uses NSFetchedResultsController to provide data;
In my opinion this is not the best way to implement datasource, and implementing it in separate class looks way better idea. But the issue it that datasource depends on search parameters in UITextField, and some other buttons selections, so every time when user types text into search field or press the any of "sorting" buttons I should update datasource (in particular fetchRequest in NSFetchedResultsController).
So, finally, my question: Is there any "best practices" of implementing datasources that depends on external parameters? Should I create separate class for datasource of leave it the way it is now? If implementing datasource as separate class - should I create datasourcedelegate for calling self-made delegate methods on delegate when datasource was updated or there is some other workarounds for this problem (I'm not considering using notifications on datasource update because as for me notifications mechanism is more global solution then I need here)?
I'm not looking for the fastest way, I just want to find out the rightest theoretical way of implementation.
Thank you all in advance :)
I personally implemented a concrete NSObject derived class, that implements UICollectionViewDataSource as well as NSFetchedResultsControllerDelegate that practically translates the fetched results controller events (object inserted, updated, deleted) to collection view events (insert, update or delete cells). You can find examples on how to do this, I took mine from here but I implemented it as a separate class instead of a category over collection view. I found my class highly reusable, in practice I use it in all of my projects where there is a need to visualize managed objects in a collection view. A similar class can be implemented also for UITableViewDataSource.
If you need to update the fetch request with the search predicate, I would subclass your newly created DataSource class, and add the logic to update the fetch request right there. Say, you add a -(void)updateSearchFilterWithText:(NSString*)text method where you add the logic to update the fetch request of the fetched results controller. Don't forget to perform fetch again afterwards and call a reloadData on the collection view!
With this architecture the view controller owns this dataSource object. Every time the user updates one of your filtering text field (or other widget), the view controller calls the updateSearchFilterWithText: of your data source object and the rest of the work is done by this later.
What you currently have is the standard approach. While there is no defined 'best' approach, what you describe is certainly a better approach.
Your view controller would own an instance of your new data source class, and would itself most likely handle the delegate methods (because these are actions to take rather than data to provide), so when anything changes in the UI the view controller should be 'pushing' these changes to the data source. No additional delegation should be required.
You shouldn't be creating your data source with the idea that text fields and buttons are directly driving changes in. Your data source should be presenting a generic interface where you can update the fetch request to execute (which covers the predicate and sorting) and change how the cell is configured (perhaps with a block). This way you keep your business logic in the view controller and the reusable data source code in another class that is reusable for other collection views / projects.

Resources