iOS: I am having a hard time with delegate definition - ios

So I know what a delegate is and I know how to implement it and everything, but this definition throws me off a little bit. "Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object." Can someone explain how this applies to something like this
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath ? What are the two objects and which object act on behalf of another object. I have an idea on what it is, but I need to make sure.

In your example, the table view controller (presumably that's the table view's delegate) acts on behalf of the table view. The class that implements the delegate method(s) acts on behalf of the class that defines the delegate interface.

Related

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.

How can I give a particular behavior to a UITableViewRowAction?

I have a standard UITableView of items. Tapping a row will bring a DetailsViewController with details about the selected item and the possibility to use it through a UIButton.
I have implemented the (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath method made available from iOS 8 and I defined two actions:
The standard deletion of the item (pretty simple stuff).
The possibility to use the item like above. I basically want this action behavior to be the same of the IBAction related to the button in the DetailsViewController.
I thought about presenting this view controller automatically and making an automatic tapping of the button without using interaction, but this could be a bit confusing for the user according to me. So I would prefer to call the IBAction method directly from the table view controller. Is it possible and how can I achieve this result?
I can provide the source code if this could help you to help me.
What you need to do is take the "use this thing" action out of your ViewController, and put it in the Model object for "thing."
Then, when you want to use your "thing" from the tableView or the DetailsViewController, you can call this function directly on the associated model object, and allow your two (possibly more) different user interfaces to perform the "use that thing" functionality appropriately based on their own UI needs.

Infinite Scroll on iOS with Swift

I'm an iOS newbie and I would like to know how to detect when the user scrolls and reaches the bottom of an UITableView so I can load new data into the table.
I would also like to know where such a method should be implemented (the tableview's class or the view controller in which this tableview exists)
Cheers!
You can use -(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath to and check if the last cell will be shown in the TableView's data source.
iOS' TableViewController takes care of that automatically. It asks its datasource only for the currently visible rows of the table (tableview.cellForRowAtIndexPath)
See the documentation for the UITableViewDatasource Protocol Reference
If you've got a "known dataset" (as in, you don't need to make a network call to fetch new data), then like #zizoft said, it'll be handled automatically in tableview.cellForRowAtIndexPath
If, however, you've got an "unknown dataset", (as in, you'll need to pull down data from the internet), you'll need to do something a bit more interesting - #ansible's suggestion would be appropriate in that case.

UITableViewDelegate and UITableViewDatasource confusion

I understood before that
Delegate pattern is used only for invoking events to delegate instance and getting controls (like size / font / etc...).
Datasource pattern is only for getting data from datasource instance (like views / title / description / etc...)
But seems it was a nice illusion, after looking to Apple's UITableViewDelegate protocol I got confused because
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
Are delegate methods (but I was thinking that they are UITableViewDatasource methods)
Is this a dirty code from Apple, or I'm missing something important too understand difference between datasource and delegate?
EDIT:
Thanks #DBD for nice answer,
here is more confusion
Here is UITableViewDelegate method that returns View for drawing
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
And also there is a configuration in UITableViewDataSource
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
And oops, we can see a method that returns a View in UITableViewDataSource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
Here we have question why cellForRowAtIndexPath: and viewForHeaderInSection: are not in UITableViewDataSource
This is how I've always thought about it.
UITableViewDataSource to be primary data. What are the actual contents of the table. How many rows? What is the content of row X?
UITableViewDelegate was secondary and display data. How tall should it be, should it display in the selected state, and call backs for "hey I'm about to do something."
However I admit I see some of it as a fine line (and I don't buy some of the choices)
UITableViewDataSource has titleForHeaderInSection.
UITableViewDelegate has viewForHeaderInSection.
So if it's pure "data" title, it's the data source, but if includes a display wrapper with a view, it's the delegate. But wait, cellForRowAtIndexPath is a view and that's part of the data source, so why would you put viewForHeaderInSection in the delegate? While I can barely see the distinction between as "cell" as data and "title view" as delegate, I think the confusion of splitting "title" methods into different protocols is not preferable. I'm sure many might disagree with me, but it's just my opinion.
I think the critical distinction here arises from what you consider "data." From your question, I think you understand "data" to mean "any return value" – that is, methods which return void are delegate methods, and methods which return non-void are data source methods (since they pass something back to the sending table view).
This can sometimes be a useful approximation, but here is inaccurate. A table view's data is the contents that it displays – the stuff in the cells, the titles of sections, etc. Any other information, including that about layout (like row height) or display (like section headers) properly belongs in the delegate, since it is not about the contents of the table – merely about how to display those contents.
The two are very often related, which is why more often than not the same UITableViewController subclass implements both the delegate and data source, but imagine: you could have one object act as the data source and vend cells, then have a different object act as the delegate and provide heights for your rows based on completely different criteria. (Imagine a table where the user can resize rows, for example. You still provide the contents of each row, but the height – the delegate's responsibility – is drawing from a very different set of information.)
dataSource and delegate are both protocols but they are separated into two terms so that we can better understand what the methods are designed to do.
This means:
The dataSource protocol defines an API that supplies the data where delegate supplies the behavior.
dataSource is in the model layer and the delegate is in the control layer.
I think this is the correct outlook.
I have the same confusion with you, until I see the Apple's document.
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.
UITableViewDataSource Protocol Reference
I don't understand your point.
The datasource protocol methods are all related to the data. The delegate protocol instead has methods regarding the appearance of the cells.

ios/iphone sdk form management best practices

I'm working on an iPhone app that will have involve a lot of forms. Currently I have a ViewController class for each settings page which has an UITableView loaded with possible settings. When someone clicks on a setting they are taken taken to a new view to enter the form value, or allowed to enter things in place.
What's the best way to keep things DRY? What pieces of this implementation could be implemented once and re-used?
When someone clicks on a settings option which goes to a new view how can I create this view and add a text field according to the data type (uitextfield or picker or something else) in code?
You can programmatically:
create view hierarchy
UIButton
UILabel
You get the idea.
However, I would recommend getting your logic working for a few of the cases, and then it should become obvious what parts are redundant as you find yourself typing in the same thing over and over. At that point, refactor to get the redundant code into a re-usable form.
HTH.
If you have a tableView, the flow is to create the viewController of the selected settings in the didSelectCell method of your tableView delegate and to push it through the current viewController's navigation controller.
here's a sample:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.navigationController pushViewController:[self settingsViewControllerAtIndexPath:indexPath] animated:YES];
}
so you'll have to implement the method:
- (UIViewController*)settingsViewControllerAtIndexPath:(NSIndexPath *)indexPath;
wich will return the viewController managing the settings associated with the selected row of your root tableView.
If your forms are pretty statics, you should consider using a xib in order to minimize the amount of code needed. it isn't a perfect answer to your "how to keep DRY" but it's neat enough ;)
Good luck.

Resources