I have been learning about Delegation and Data Sources for iOS programming and need to ask, is there any differences that you need to do when you make a data source protocol than a delegate protocol?
Also how can I implement a delegate for many same objects in one delegate? Example one object with many unique custom alerts.
--Edit--
An example for the second part:
One object that has four different alerts each with different buttons. Since object needs to dictate how each button works by being a delegate for the alerts. How would I set the delegate methods to determine each alert?
Both types of objects more or less behave the same way, it is a matter of what they do that is the question.
A delegate type object responds to actions that another object takes. For example, the UITableViewDelegate protocol has methods such as didSelectRowAtIndexPath for performing actions upon a user selecting a particular row in a table.
Whereas a data source type object gives data to another object. For example again, the UITableViewDataSource protocol has methods such as cellForRowAtIndexPath and numberOfRowsInSection dictating what should be displayed in the table.
There is no hard difference between the two in terms of compilation, it is simply a coding style to make what objects do what very clear to the user of the code.
EDIT:
To answer your second question: if you want each alert to respond differently, you will need to write a different delegate for each alert. For example, if one of your alerts is a save confirmation alert (perhaps you are going to overwrite a file, and it pops up to confirm thats what the user would like to do), you would have an object such as:
#interface SaveConfirmAlertDelegate : NSObject<UIAlertViewDelegate>
#end
And in the #implementation for SaveConfirmAlertDelegate you would implement the proper save feature depending on which button the user pressed in the alert.
When you create an alert view, you specify what the delegate object should be, this does not have to be self. You could have your four delegates stored as different objects and set them on the alerts as necessary.
I hope this clears things up
Related
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.
In detail view controller I have formlist. after fill that form I'm storing into array after Save Button click then I'm passing that array into MasterView and Showing Count Of Forms.
You should take a look on design patterns. In your above case delegation would be preferred. Notification is another option but it should be used for broadcasting a message.
objects receiving notifications can react only after the event has occurred. This is a significant difference from delegation. The delegate is given a chance to reject or modify the operation proposed by the delegating object. Observing objects, on the other hand, cannot directly affect an impending operation
You can read more about on design pattern and viewcontroller interaction:
How do I set up a simple delegate to communicate between two view controllers?
http://www.informit.com/articles/article.aspx?p=2091958
http://blog.shinetech.com/2011/06/14/delegation-notification-and-observation/
I noticed in using UITableView, UICollectionView, UIPickerView, UIScrollView, ..., and numerous other UIKit classes that the UIViewController containing the object instance often bears the role of DataSource and Delegate.
I understand from Apple's documentation what these data source and delegate methods are called, and how to implement them... for a single instance of each class.
My question is, how do you handle different instances in the same UIViewController? For example, if I have two UICollectionViews, or three UIPickerViews, ...., or fifty UIScrollViews? I can implement the data source method only once per UIViewController, but I somehow have to tell the program different instructions?
The only thing I can conceive is a gigantic switch statement or a bunch of cascading if-else if-else comparing the input to the delegate or data source method to each object instance in the UIViewController, which might get out of hand if there are many.
While we're used to using our view controller as the delegate, there's no need to do so. You can actually create NSObject subclasses that conform to the delegate protocol in question. You can then instantiate those objects and use them as the delegates of the UI objects (or whatever) as needed.
For example, consider a scene where I have two text fields, one which permits only numeric values, and one that does not accept numeric values. I can write a separate delegate object for each type of text field.
If implementing this programmatically, I would manually instantiate the two delegate objects, keep some strong references to them in my view controller, and then in viewDidLoad I can set each text field's delegate to be the appropriate delegate object.
If doing this in Interface Builder, you can actually drag an "Object" from the "Object Library" onto the scene (either in the bar above the scene or the document outline to the left of the scene):
You can then specify the class for this object:
Repeat this for all of your delegate objects:
And finally, you can go to your text field and specify the delegate by control dragging to the delegate object you added to the scene:
Doing it in Interface Builder means that it completely takes care of the instantiation of this delegate object for me and I have to do nothing in view controller's code.
Bottom line, if you want distinct behavior for a UI object, you can just instantiate a separate delegate object that manifests the desired behavior, and use that as the UI object's delegate. This pattern of instantiating separate delegate objects is common in iOS 7 custom transitions (where we have all sorts of delegate objects banging about), but can be used in this context, too.
BTW, you can obviously just subclass the UI control in question, too, and further encapsulate the logic there. That works equally well.
By creating referencing outlet for each controller,for example if you have two UITableView ,You can create outlet for each such as table1 and table2. To set number of rows in a section for these table ,you can code like follow
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == table1) {
return 10;
}
if (tableView == table2) {
return 5;
}
return 1;
}
You can create independent UIViews for each tableView or collection view with it's own .swift and .xib (and maybe if they are very similar you can reuse them). Doing that you will have the tableView and collecionView delegate methods in separated files and everything will be more clear. In your view controller you will just have to place the views, but you won't have any delegate methods there.
Well you are asking to differentiate the views with datasource & delegate in a smarter way. But you are overthinking this thing.
Everyone takes the different tableviews or pickers because they wan't be the same.
Otherwise they can be reused.
Now if they are going to be different from others then ultimately somewhere in your code you have to put the if...else or case statements. For example for tableview while setting the value of an UILabel or any value in your UITableViewCell.
If you are facing a such an issue that you have to put that many scrollviews or something in only one UIViewController then its an impossible situation if you are following the coding standards or may be your app design is faulty.
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.
I'm building a simple calendar application based in a single view controller. The view controller has a hierarchy as follows:
CDViewController
CalendarView
EventView
AgendaView
TPKeyboardAvoidingTableView
EventInfoCell
My question specifically pertains to the EventInfoCell within my AgendaView. The Cell has various ways of laying out textFields and textViews, depending on the information that needs to be displayed. These textfields and textviews are enabled/editable based on the tableview's edit status and edit/delete core data objects. When the strings within these change, the cell needs to alert the managedObjectContext to save or delete an object, update the model within the agendaView that populates it's tableView, and update the model that pertains to all events for the calendar. My current configuration makes the viewController the delegate of EventInfoCell, but this complicates the update for the agendaView model. It seems almost counterproductive to set the EventInfoCell delegate to be the AgendaView, tell it when information changes, and then have the AgendaView pass the word on to it's delegate (the viewController), but if it is more compliant to MVC than bypassing the agendaView altogether, I will gladly implement it. I'm trying to figure out what is the better design pattern, any input is greatly appreciated.
"It seems almost counterproductive to set the EventInfoCell delegate to be the AgendaView, tell it when information changes, and then have the AgendaView pass the word on to it's delegate"
Why does this seem counterproductive? This is the way I would handle it. If you don't do it this way then you are going to have to open up some sort of properties or a notification or something in the AgendaView for the ViewController to pass the information back to it. That sounds more counterproductive to me than passing the information up the chain. Plus, you may eventually have some sort of changes in the EventInfoCell that require its delegate to act, but do not necessarily alter the Core Data model. So, I think you should pass the delegation up the chain.