UICollectionViewDataSource, UICollectionViewDelegate in UIView - ios

I have created a UIView with UICollectionView.
In the interface declaration of the UIView I have conformed to the UICollectionViewDataSource, UICollectionViewDelegate protocols:
#interface TestOverview : UIView <UICollectionViewDataSource, UICollectionViewDelegate>
But when I run the app, it crashes and i get this error:-
error: -[TestScreenViewController collectionView:numberOfItemsInSection:]: unrecognized selector sent to instance.
Just to be clear the method collectionView:numberOfItemsInSection is in the UIView (TestOverview), which was declared to be the delegate of the UICollectionView. So why does it expect to recieve it in the UIViewController(TestScreenViewController), which contains the UIView that contains the UICollectionView?

First of all, it would be better if you used a view controller as the delegate of your UICollectionView. That's what they are there for. Second of all, not only you need to declare that TestOverview implements the UICollectionViewDataSource and UICollectionViewDelegate protocols, but also you need to tell the UICollectionView instance who their delegate and data source respectively are. You can either do it in code like this:
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
Or in the Interface Builder, by binding the dataSource and delegate items to TestOverview.

It is better to user viewcontroller as collectionview delegate than a uiview.
self.collectionView.delegate = self;
self.collectionView.dataSource = self;

Related

Why does UICollectionView conform to UICollectionViewDelegateFlowLayout by default?

I'm just confused with the following code that gets executed in a UICollectionViewController instantiated from a xib file:
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 1.0;
}
which is declared in the protocol UICollectionViewDelegateFlowLayout. However, there is nowhere in the UICollectionViewController showing that it would conform to this protocol, as declared in the UICollectionViewController:
NS_CLASS_AVAILABLE_IOS(6_0) #interface UICollectionViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource>
Can anyway explain why UICollectionViewController would conform to UICollectionViewDelegateFlowLayout?
By default, the class of a collection view's layout when dragged into a xib/storyboard is UICollectionViewFlowLayout, which is why by default the delegate methods for UICollectionViewDelegateFlowLayout are called. If you were to change the layout object's class in the xib/storyboard, none of the methods specific to UICollectionViewDelegateFlowLayout would be called.
Also, UICollectionViewController may privately conform to UICollectionViewDelegateFlowLayout, or it may not. It doesn't really matter because a class doesn't technically have to explicitly conform to a protocol in order to implement and respond to methods in that protocol.

How to use UIScrollViewDelegate methods on a tableView added to a UIViewController?

how could we use the UIScrollViewDelegate methods on a tableView that is added to a UIViewController? It works fine when I subclass the UITableViewController, but in my case, the tableView is added inside a UIViewController. The delegate and datasource are linked to self, I added UIScrollViewDelegate as a protocol, but the delegate methods are not recognized by the viewController.
Thanks
UITableViewDelegate inherits from UIScrollViewDelegate.
If you determine that object is delegate of table view, it would be also a delegate of scrollView.
Here is how to get this done in two steps:
ViewController.h
Your UIViewController must implement both the UITableViewDelegate and UIScrollViewDelegate. If you are working with interface builder, you will also have an IBOutlet for the UITableView:
#interface ViewController : UIViewController<UITableViewDelegate, UIScrollViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tableView;
ViewController.m
In your implementation code, you have to specify that ViewController is the tableview's delegate. You also need to implement one of UIScrollView's delegate methods to be notified of the scroll:
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(#"Scrollview did scroll");
}

UITableView scrollView delegate not called

I have a tableview set inside a UIViewController
#property (strong, nonatomic) IBOutlet UITableView *tableView;
with delegates set in viewDidLoad
self.tableView.delegate = self;
self.tableView.dataSource = self;
The following methods never get called:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
Isn't tableviewdelegate supposed to conform to uiscrollviewdelegate as well?
Any idea why these methods are never called?
You need to do two things:
1) Set the UITableView's delegate property, as was suggested by others.
AND
2) Add conformance to the UITableViewDelegate protocol.
If you do just the first step, the UIScrollViewDelegate methods will not be called.
Add the delegate lines in awakeFromNib instead of viewDidLoad. I had the same problem and that worked.

UITableView in a xib is not calling cellForRowAtIndex

I have a XIB that has a bunch of views in it (iPad). One of the views is a UITableView. The delegate was set via IB. When you run the app cellForRowAtIndex is not being called. As a matter of fact, in this file, there is also no numberOfRowsInSection or numberOfSections methods. There is only a didSelectRowAtIndexPath method.
So I wrote a cellForRowAtIndex and manually set self.table.delegate = self.
If I click a cell the didSelectRowAtIndexPath is executed.
I honestly am at a loss? How can this even happen?
Add:
self.table.dataSource = self;
cellForRowAtIndexis a datasource protocol method, so you must set the datasource to self as well in order for the controller to respond to the datasource protocol.
If this controller is anything other than a UITableViewController, do not forget to add the following to your .h file:
#interface myViewController: UIViewController <UITableViewDelegate, UITableViewDataSource> {}
In your .h you need to add the Datasource and Delegate declarations
#interface HDMainViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
and in you .m file where you create your tableview you need to set
tableview.delegate = self;
tableview.dataSource = self;
Now your dataSource and Delegate methods should work
I'm not sure what is causing the problem, however an easy fix is that in your -(void)viewDidLoad method you could call [self.table reloadData] which forces it to manually call all of the functions
Somethign else that occurred to me is that you said "numberOfRowsInSection or numberOfSections is not implemented"... Those methods are required for a table view and oyu must make sure to implement them. That could very well be the problem

UITableView setter method functions not being called

functions like this one:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
NSLog(#"called")
return 1;
}
aren't being called, because the log doesn't appear at the console. I tried using
[table realoadData]
but it still doesn't work
Make sure that you have both the UITableViewDataSource and UITableViewDelegate set to the class that this method is located in
.h
#interface class_name : UIViewController <UITableViewDelegate, UITableViewDataSource>
{ UITableView *tableView; }
.m
in the viewDidLoad (or any other loading method)
tableView.delegate = self;
tableView.dataSource = self;
If you are subclassing UITableViewController, it should be working already
hope that helps!
In Nib file, you need to outlet tableview.
Your subclass must have UITableViewDataSource and UITableViewDelegate.
Assign tableview.delegate = self and tableView.dataSource = self;

Resources