How to link Table dataSource and delegate outlets to UITableViewController? - ios

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.

Related

Communicating between UIViewController and UITableViewDelegate

I have a UIViewController which contains a UITableView (amongst other views).
The UITableView could get its cells from one of two UITableDataSource, depending on some condition.
My UITableDataSource class also acts as my UITableViewDelegate.
When a cell is selected (tableView:didSelectRowAtIndexPath) I may want to perform an action on the UIViewController, such as performSegue or show an alert.
What would be the best way to do this?
Add a weak reference to the UIViewController inside each datasource/delegate class
Create a delegate per datasource/delegate class which calls functions inside my UIViewController
Your suggestion here!
I considered making my UIViewController the UITableViewDelegate but as the cells are different depending on the source I thought it would get messy.
Note: I say "best way" but really I am just interested in alternate approaches
The most common approach is to subclass UITableViewController and implement UITableViewDelegate and UITableDataSource there. You can return whichever cell you require in cellForRowAtIndexPathbased on any state in your controller class.

How to use TableViewController Class in TableView?

In my App I want to display a TWTRTimelineViewController (TableViewController) in an UIViewController. But the Code for the TWTRTimelineViewController is only working in an UITableViewController Class and not in an UITableView Classe. Is there a way to solve this, for example to display an UITableViewController at a y-postition in an UIViewController?
Thanks!
You should create a UIViewController than include a tableView using the storyboard and connect it with the UIViewController (#IBOutlet). Next you will set a identifier to the tableView prototype cell. Than in your UIViewController you will extend the delegates UITableViewDelegate and UITableViewDataSource and implement the protocols.
This tutorial is pretty much detailed and will give you all the steps to achieve what you expect.
You can not set UITableViewController custom class in UITableView,if the 3rd party class you are using is UITableViewController then you must use it in UITableViewController from storyboard

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.

How does UITableViewController knows its dataSource and delegate

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;

Will a UIViewController subclass also affect my UITableViewControllers?

I need to add a common method to all my view controllers no matter what type they are. I notice though that some of my viewcontrollers inherit from UIViewController and some from UITableViewControllers.
How do I write a subclass that can be used for both?
UITableViewController inherits from UIViewController, so if you want to be able to call your custom method from both, you can write a category on UIViewController and then call methods from that category in any subclass of either UIViewController or UITableViewController. Here's a link to Apple's docs on categories and extensions. http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/chapters/occategories.html
if you add a category to UIViewController, you will be able to call those methods on UITableViewController subclasses, as UITableViewController is a subclass of UIViewController

Resources