How does UITableViewController knows its dataSource and delegate - ios

I am following the BigNerdRanch iOS Programming book and I am on this one chapter that deals with UITableViewController. I have been wondering however where UITableViewController finds out about its delegate and dataSource. Currently I have it as
#interface ItemsViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate>
But there is nothing that looks like:
[self.tableView setDelegate:self]
I am just wondering how the UITableViewController finds out about its delegate and dataSource

If you were setting up the UITableView yourself, you would have to point it to a delegate and data source.
UITableViewController sets up the UITableView and sets the delegate and dataSource properties to itself. When you subclass UITableViewController, you get this behavior for free.
Your question is flawed because UITableViewController doesn't have a dataSource and delegate, the UITableView it is controlling does. And the UITableViewController is the dataSource and delegate because it sets things up that way.

You either set the delegate and dataSource on the table view object (in the xib or storyboard file) via Interface Builder (within Xcode) or programatically, via ".delegate =" ([self.tableView setDelegate: _____) and ".datasource=".
Note, you're setting these things on the table view managed by the table view controller (i.e. two distinct objects).

First of all the declaration:
#interface ItemsViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate>
is only an indication that your View Controller is responsible for providing DataSource and Delegate methods.
This is just an hint (you are just saying that your view is conforming to that protocols) to someone viewing your code and a hint to Xcode that you need to provided the required protocol implementations (else Xcode will give you a warning that you haven't implemented the datasource and delegate methods, and again only for the required and not optional methods).
You actually are setting the datasource and delegate of the TableView in the Interface Builder.
Click on the TableView in IB, select from the right pane the Outlets option, then click on datasource and drag over to the "File's Owner" to set the datasource.
Same for the delegate.
If you are creating the table in code, you need to declare the datasource and delegate yourself, this way:
tableview.datasource = self;
tableview.delegate = self;

Related

How to link Table dataSource and delegate outlets to UITableViewController?

I'm new to Swift/iOS development.
I have a UITableView in my storyboard that I want to populate with some data. In my attempt to do so, I created a class that inherits from UITableViewController. The implementation is not yet complete, but my understanding is that by inheriting from this class I can provide an IBOutlet to both dataSource and delegate.
When I try to drag the outlet into the source file, I don't get the insertion point that I got when I tested this before. See image below:
What do I have to do to define this class as the handler for the UITableView?
Set your viewController to inherit from UIViewController, not from UITableViewController (It seems like your IB is set up like that).
Do not forget to set your class to ZeroconfTableController on the interface builder.
Than, you will be able to set the delegate and datasource. NOTE: the delegate and the datasource will not create IBOutlets.
Assign the delegate and the dataSource the following way:
Also make sure, your viewController conforms to the protocols.
class ZeroconfTableController: UIViewController, UITableViewDataSource, UITableViewDelegate {
In your storyboard, select the UITableView and change this to the name of your UITableViewController subclass. You then do not need to do any linking stuff.
If you're using your own UITableView, inherit from UIViewController, not UITableViewController.
If however, you want to use a UITableViewController (which personally I don't use) in your storyboard, then do inherit from UITableViewController. In this case you won't have to wire up the UITableViewDataSource nor the UITableViewDelegate.

CollectionViewController, should I subclass or implement its delegate/datasource with a normal UIViewController?

When I am implementing a viewController with CollectionView, whether should I drag drop a CollectionViewController from storyBoard then creating a MyCollectionViewController class, which is a subclass of CollectionViewController?
OR should I just use a normal viewController, add a collection view to it,and implement its dataSource and delegate protocol?
I know one of the advantage for later is that you may have multiple CollectionViews under one ViewController? But what other pros and cons?
And how it applies to the TableViewController, as they are quite similar to each other.
UICollectionViewController inherits from UIViewController, so it essentially is a UIViewController with a UICollectionView and some built-in functionality. Per the documentation, this functionality is:
If the collection view controller has an assigned nib file or was
loaded from a storyboard, it loads its view from the corresponding nib
file or storyboard. If you create the collection view controller
programmatically, it automatically creates a new unconfigured
collection view object, which you can access using the collectionView
property.
When loading a collection view from a storyboard or nib file, the data
source and delegate objects for the collection view are obtained from
the nib file. If a data source or delegate is not specified, the
collection view controller assigns itself to the unspecified role.
When the collection view is about to appear for the first time, the
collection view controller reloads the collection view data. It also
clears the current selection every time the view is displayed. You can
change this behavior by setting the value of the
clearsSelectionOnViewWillAppear property to NO.
I prefer to always subclass UIViewController and add a UICollectionView in storyboard. This means that my subclass has to implement the UICollectionViewDataSource and UICollectionViewDelegate protocols and I have to set them in storyboard, and I have to make sure that when the view controller appears that I reload the collection view. But because I implement the behavior myself, it feels like I have more control. If you tend to use the regular, default behavior, then perhaps go with the UICollectionViewController to save time.
I feel exactly the same way about UITableViewController and UIViewController with a UITableView - I prefer the latter for exactly the same reason.
If you are sure that your UI will have only CollectionView, use CollectionViewController.
This rule applies for tableViews also.
Personally I started to follow a different approach in general. I use plain UIViewController to wich I add UITableView or UICollectionView. In the controller I only create a IBOutlet for the view.
class MyViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
}
Next I create a separate object as my datasource
class MyDataSource: NSObject, UITableViewDataSource {
init(with tableView: UITableView){
//Register cells, configure tableview, etc
}
numberOf...
cellForRowAt...
}
Then in my view controller, i have a lazy var with the datasource:
lazy var dataSource: MyDataSource = { return MyDataSource(with: self.tableView) }()
And finally in viewDidLoad I set the datasource to the tableview:
tableView.dataSource = dataSource
By doing this, you can keep your viewcontroller really clean and small as it should be. You prevent the MVC (massive view controller) problem and follow the principle of single responsibilities. Also your datasource is now reusable across multiple view controllers.

Can a property of a UITableView be the UITableView Delegate and DataSource

I have a custom view that's a bit of a hack. Basically it's a UIView with tableView as it's property, with additional views in the tableView that need their own delegates. I need a viewController for the UITableView and can't make the UIView it's delegate according to this SO link Custom UIView as UITableView delegate and datasource?.
Can I make the UITableView have a property of UIViewController and set that UIViewController as the tableView's delegate?
In this case according to OOP, the UITableView has a UIViewController so technically, I could expect this to work. But, I am wondering if down the line somewhere this could create problems since the UITableView and UIViewController are coupled in this way.
You don't need a UIViewController for the UITableView - you just need an object or objects that implement the data source and a delegate protocols. As per the accepted answer on the question you linked to you can use a separate controller class to provide this.
The right answer depends a little on how the table is used with your UIView subclass.
If the table will always have the same content (Say a list of months) and there is no value in exposing or abstracting the properties then you can code the delegate and dataSource inside your UIView subclass or in an assistant class.
If the table content will vary depending on how the UIView is used (say a list of people where you don't know what the list is - friends, relatives, employees...) then it would make sense to simply expose the tableview's datasource (and delegate if necessary) properties via your UIView subclass

Merge two viewcontroller's code using addsubview in IOS

I want to break my code into 3 files and them up via addsubview. For ex. i have a masterview, mastreview contains a currentView. CurrentView contains 1 webview and 1 tableview.
Now, i have written all code in one file and it works like a charm. But i want to make it abstract and loosely coupled . So i need a separate file ex. webviewController to implement its delegate and function related to it AND tableviewController to implement its delegate and functions related to it. And add both by addsubview, alloc init in masterview file.
I did it my way,though i was able to addsubview on CurrentView, the problem was my delegate functions are not working properly.
Also, i am confused about tableviewController should inherit UIViewController or UIView or UITableView.
it would be good if anyone can guide or send some link related to it, any example...???
Actually you should have the app crashing if the delegates are not retained somewhere.
If you do link the object with view controller to be it's delegate at Interface Builder, the view controller will be destroyed after it's outlets so you don't care. If you are creating separate class for the delegate, you should care about it's lifecycle, standard classes do not retain their delegates so you have to retain it on the same level where you are retaining the delegated object. Like if you are creating a UITableView subview and you have MyTVDelegate class, you should create the delegate instance, assign it to tableView.delegate and retain as viewController var so that viewController will dealloc both subviews and their delegates when needed.
For the second question, UITableviewController inherits UIViewController as you can see at header files (command+click on UITableviewController), and UITableView inherits UIView. Every viewcontroller should have the root view of UIView and I believe UITableviewController has UITableView as it's root view.

Trying to adding a UITableView into a view hierchary with it's own view controller

I have a view hierarchy that has a UIViewController as Files Owner in the XIB.
I need to add a UITableView into the hierarchy that has it's own controller (a UITableViewController subclass) because I am implementing a pull-to-refresh UI using http://github.com/leah/PullToRefresh
What I did:
created the new UITableViewController subclass, BuddyTableViewController
implemented the datasource & delegate methods
added the UITableView into the hierarchy in Interface Builder
dropped an NSObject into the XIB and set the class to BuddyTableViewController
set the delegate & datasource of the tableview to BuddyTableViewController and hooked the UITableView to the tableView property of BuddyTableViewController
When the view displays it crashes immediately.
When running in debug with NSZombieEnable=YES reveals the message:
*** -[BuddyTableViewController numberOfSectionsInTableView:]: message sent to deallocated instance 0x69551d0
numberOfSectionsInTableView only contains return 1;
I don't understand why BuddyTableViewController is being deallocated.
You need to hook it up to an outlet in the owner, having it as delegate and data source is not enough because neither of those retains it. If the object is not retained by you it will be autoreleased.

Resources