UICollectionView: Do I need to use an UICollectionViewController? - ios

I am using XCode5 and iOS7.
Is it possible to embed a UICollectionView into a normal UIViewController class and have the UIViewController implement the methods?
Or do I need the UICollectionViewController?
Which methods are required at minimum?

Yes it is possible to implement UICollectionView without UICollectionViewController. CollectionViews are just like tableView.
As you probably already know, when you use a UITableView you have to set a data source and a delegate in order to provide the data to display and handle events (like row selection).
Similarly, when you use a UICollectionView you have to set a data source and a delegate as well. Their roles are the following:
1. The data source (UICollectionViewDataSource) returns information about the number of items in the collection view and their views.
2. The delegate (UICollectionViewDelegate) is notified when events happen such as cells being selected, highlighted, or removed.
And new to UICollectionView, you have a third protocol you must implement – a protocol specific to the layout manager you are using for the collection view.

You can use a UICollectionView, you'll need the UICollectionView to conform to the UICollectionViewDelegate and UICollectionViewDataSource protocols.
so you will need at a minimum;
numberOfSectionsInCollectionView, numberOfItemsInSection and you'll need to implement cellForItemAtIndexPath to create the cells. Obviously you'll also need to define the Cell

Answer is NO. UICollectionView is subclass of UIVIew and can be added to any view you wish.
Since UIVIewController has view property you can add UICollectionView to it using:
[self.view addSubview:self.collectionView];
Here is a great tutorial with sample project where you can see how to implement UICollectionView in your custom UIViewController subclass:
http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12

You don't need an UICollectionViewController. Just make sure, that your ViewController implements the UICollectionViewDelegate and UICollectionViewDataSource.
This example should help you with the topic UICollectionView:
http://adoptioncurve.net/archives/2012/09/a-simple-uicollectionview-tutorial/

Related

Best Practice For Multiple Usage Of UICollectionView

I have a main UICollectionView with custom UICollectionViewCells. And I use it in multiple UIViewControllers.
I have a timeline, likes, profile which use same UICollectionView.
What is the best practice of declaring UICollectionView with this kind of situations?
I tried to create a class named MainProductCollectionView which inherits from UIViewController. And in TimeLineViewController I use it like below.
let vc = MainProductCollectionView() //init
self.view.addSubview(vc.collectionView)
But I'm not sure if it is best way to use. Thank you.
There are 2 solutions:
Create a custom collectionView that inherit from UICollectionView and contains all the delegate methods like celForItemAtIndexPath numberOfItemsInSection ...
Or
Create your collectionViewCell in a xib file and then use yourCollectionView.register(cellType: CustomCell.self)

Migrate UITableViewController to UITableView

I currently have a UITableViewController, but would like to add a label at the bottom of the screen. I think the easiest way to do this would be to just use a UIViewController with a UITableView. Is there an easy way to migrate over? I've noticed some functionally is different; for example UITableViewController has a numberOfSections method, whereas UITableView does not have that method. Also is it possible to use a UIViewController as the delegate for a UITableView? Thanks in advance.
Update: I have attached a picture of the code, and the error given when trying to implement UITableViewDataSource.
You can do this. You need to implement the UITableViewDelegate and include the UITableViewDatasource in your View Controller, then you can use the functions you were using in your TableViewController.
Basically what you should do is add a tableview in the interface builder, or programmatically (depending on your choice). If it's done through the interface builder then outlet it to your Controller. Add the Delegate to your class, and you would have access to the tableViewFunctions (cellForRow, numberOfItems, numberOfSections, didSelectRow etc...).
Also, when you create the tableview specify the tableview.delegate = self and tableview.datasource = self.
As far as I know, the methods are the same, you just won't need the override bit before each one if its just a UITableView. You can use UIViewController as the delegate, yes, by setting myTableView.delegate = self in its viewDidLoad method.
If its just a label you need however, you might consider adding one programatically? Similar results achieved with a no data label for example - see here. You could then play around with the positioning.
This error is thrown because you need to set dataSource to your TableView Object like self.tableView.dataSource = self. After this you can use freely all methods for UITableView including numberOfSections as you mentioned.

Add collectionView to Header

I'm trying to add a collectionView to my CollectionView header. A collectionView inside a collectionView I guess. I've got the header setup and I get a blank collectionView in the header part when I run the app but where can I programme this collectionView.
I've got an outlet for it created in the header.swift file which I can access in my main collectionView file but I can't configure the cells, set the number of sections etc. If it was just a label in the header I could set the text etc here but I'm not sure how to configure a collectionView here.
I tried creating a CollectionViewController file and just linking that to the colectionView in the header but that doesn't work. How can I create a subclass for that collectionView (in the header)?
Swift 3
Okay heres the deal: I guess you use a UICollectionViewController or a UIViewController with a UICollectionView which implements the UICollectionViewDataSource protocol, right? This will massively and unnecessarily bloat your UIViewController.
A better way would be to create a separate object to implment the DataSource of your collection views. One for your main collection view and one for the header collection view. Then you just have to wire them up. You must keep a reference to your data source objects somewhere.
So usually, in viewDidLoad of your view controller you get your collection view and call collectionView.delegate = theDataSourceObject.
theDataSourceObject could be a lazy var in your UIViewController lazy var myDataSourceObject = MyDataSource()
Then, wherever you create your header collection view, you also set its datasource. I hope you understand what I mean and this answer helps you. If you should learn one thing from it than that your view controllers don't necessarily have to be the datasource and/or the delegate of your UITableView or UICollectionView.
They can be totally different objects. A singleton would be an option as well as storing instance variables of your datasource.

didDeselectItemAtIndexPath function is not being called in programmatically created UICollectionView

I have created a UICollectionView programmatically. Its cells also contain programmatically created UILabel, UIView and UIImageView. The view that contains this collection view has also been created programmatically. I've set its datasource and delegate to self. The userInteractionEnabled property of label, view and image view has also been set to false. The allowsMultipleSelection property of collection view is also set to true.
The problem is that the didSelectItemAtIndexPath function is called whenever I touch the cells. But didDeselectItemAtIndexPath function is never called. I tried to set the cell.selected property to true/false as required but no aid to my problem.
Please help!! I've spent many hours searching about it but no result!!
Thanks for you responses.
Well, both this functions are called according to UICollectionViewDelegate in object which conforms to it. I highly advertise you to check this points:
After creation your custom collectionView don't forget to set it delegate property.
Implement this methods in your delegate object. -collectionView:didSelectItemAtIndexPath: or -collectionView:didDeselectItemAtIndexPath: and put there simple NSLog() output or breakpoints
Don't forget to set up UICollectionView property allowsSelection to YES
Face the result
Important notes
1. If you call UICollectionView methods like -selectItemAtIndexPath:animated:scrollPosition: or -deselectItemAtIndexPath:animated: any of this action will not be triggered nor notification will be received. As you remember, the same as in UITableViewClass
2. UICollectionView property allowsMultiplySelection allows you to switch between collection cells states
3. It doesn't matter where you create you elements. It just need to be setup correctly.
Hope this may help you.

How to Subclass UICollectionView?

I would like to customize the UICollectionView, but all the tutorials on the web and in books use UICollectionViewController which I do not want to use. I'm combining different kinds of UICollectionViews in the same UIViewController, so I don't want to limit myself by subclassing UICollectionViewController, which doesn't allow me to place several UICollectionViews in the same viewController along with other objects and labels.
How do I subclass UICollectionView? Specifically, what kinds of methods need to be overwritten? How do I layout what goes into it (i.e. where to put a text label, image, etc.)? I'm familiar with the data source / delegate protocols, but not quite sure how to customize the cell's look, placement of sub items within the cell, what classes need to be overwritten/sub classed, etc.
A list of things I need to do would be much appreciated!
Thanks!
You can do it like this link
Here are some good Examples to customize your collectionview.
Use WaterfallCollectionView from this. It may help you.
I believe that you don't need to sub-class UICollectionView but you need to sub-class UICollectionViewFlowLayout.
UICollectionViewFlowLayout is the object which manages the display of the collection view items and it is highly customizable.
I suggest you follow WWDC 2012:Advanced Collection Views and Building Custom Layouts
The best tutorial which worked for me was by Apple called Using the Flow Layout.
I think you wont have to subclass a collection view. What you would need instead is subclassing UICollectionViewLayout to customize the positioning of cells within the collection view. And if you are looking for a customized look of a cell, you would also have to subclass UICollectionViewCell and assign the sub classed cells to the Collection View.
The below links might help you,
https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCustomLayouts/CreatingCustomLayouts.html
http://adoptioncurve.net/archives/2012/09/a-simple-uicollectionview-tutorial/

Resources