Why does UICollectionView conform to UICollectionViewDelegateFlowLayout by default? - ios

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.

Related

How define a Type like `UIView<UITableViewDelegate>`(oc code) in swift?

An object of UIView or subclass of UIView and comforms to UITableViewDelegate protocol.
I need a generic type rather than a spesific type. So that developer who use it can define a freely. The oc code we can do like this:
#property (strong) UIView<SomeDelegate> *contentView;
I am thinking you are just looking for something like this
class MyView : UIView, UITableViewDelegate {
}
You will most likely have to add UITableViewDatasource protocol as well
Best practice you can use extension method for Current Class along with delegate or datasource:
class MyView : UIView {
}
extension MyView: UITableViewDelegate,UITableViewDataSource
{
}

Is there a smart way to superclass both UITableviewDataSource and a UICollectionViewDatasource

I would like to have 1 super class for both UITableviewDataSource and UICollectionViewDatasource. What is the right way to do it?
You can declare your own protocol and state that the new protocol conforms to UITableViewDataSource and UICollectionViewDataSource. Let's call it CombinedProtocol. Then anything that says it implements the CombinedProtocol will have to implement the usual table view and collection view methods.
#protocol CombinedProtocol <NSObject, UITableViewDataSource, UICollectionViewDataSource>
// add any additional methods if you want
#end

Accessing a TableView within a ViewController

I've got a ViewController that has a UITableView within it. When I'm watching tutorials people are using things like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _Title.count;
}
How am I able to generate the stubs without firstly creating the class with them in. When I made the class I selected it as a UIViewController. I've been playing around trying to auto generate the stubs but all to no avail.
Simply add the UITableViewDataSource (and most likely the UITableViewDelegate) to your UIViewController declaration. Example:
// MyViewController.h
#interface MyViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
// ...
#end
After that your implementation file MyViewcontroller.m should help you with the code completion.
One note: don't forget to set yourself as dataSource:
_tableview.dataSource = self;
If you added the tableview by code, you need to create a property (weak) in order to have a reference to your table view after adding it to your view controller's subview. If you add it by using interface builder, you need to create a iboutlet property that will allow you to "bind" your table view property with the xib/storyboard file representing your view controller. Alternatively, you can use UITableViewController as the parent class of your view controller. This class already has a property to access the table view in your view controller.
Tell your controller that you need to conform to the table view protocols and they will start to auto-complete when you try to type them in. You can check the docs of a protocol to find the available methods. Checking the UITableView docs would tell you about the relevant data source and delegate:
The data source must adopt the UITableViewDataSource protocol and the delegate must adopt the UITableViewDelegate protocol.
In your header file:
#interface MyViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
You have a couple of options.
You could make your class inherit from UITableViewController instead of UIViewController. This will give you a tableView so you don't need to make one.
Or...
Your UIViewController could implement the protocols UITableViewDataSource and UITableViewDelegate. Then set the dataSource and delegate properties of your table view to self (your view controller containing the table).
-First of all you may need to add datasource and delegate of UITableViewController in your UIViewController header file
#interface MyViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
and then implement the required and optional methods to populate the data in your _tableView.
Sample Code for TableView demonstration by Apple:
https://developer.apple.com/library/ios/samplecode/TableViewSuite/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007318

subclassing UIViewController in iOS

I got confused on subclassing a UIViewController in iOS, I have a parent viewcontroller which conforms the UICollectionViewDataSource protocol (in its private interface inside the implementation file).
/* Parent.m */
#interface Parent () <UICollectionViewDataSource>
// this CollectionView is connected to storyboard
#property (weak, nonatomic) IBOutlet UICollectionView *CollectionView;
#end
#implementation Parent
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.somecount;
}
#end
And then I create a child view controller which inherited from parent. The child knows nothing about UICollectionViewDataSource as the datasource implemented in parent's private interface.
/* child.h */
#interface child : parent
// nothing was mentioned here that parent has a method to set the count using 'somecount'
#end
Then I set the viewcontroller from mainstoryboard as the child view controller.
how come ios get the value from parent's property 'somecount' and set the value for child?
thanks.
You ask:
how come ios get the value from parent's property somecount and set the value for child?
A subclass always inherits the properties and methods of its super class. They may or may not be public interfaces (you haven't shown us the declaration of somecount, so we don't know), but regardless, they are there and will be resolved at runtime (unless you override those methods/properties in the child, which you don't appear to be doing). If there are private methods and properties in parent, you might not be visible at compile-time from the child, but they're still there and will behave properly at runtime.
So, when the scene with the collection view specifies the child as the data source for the collection view, if child doesn't implement those UICollectionViewDataSource methods, it will automatically end up invoking those of the parent. Likewise, when any of those methods refer to somecount, if the child doesn't override it, it again will end up calling the appropriate accessor methods of the parent. Bottom line, child automatically inherits all of the behaviors, methods, and properties of the parent.

UICollectionViewDataSource, UICollectionViewDelegate in UIView

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;

Resources