Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIViewController within UICollectionView

I have a full-screen UICollectionView in my app. It scrolls horizontally and each cell fills the collection view's bounds. The collection view is managed by a UIViewController.

Given that each "page" is reasonably complex, it makes sense for each page itself to be managed by an associated UIViewController. iOS 5 has support for view controller containment, so that the child controllers should receive the appropriate lifecycle methods (e.g. viewWillAppear:, etc) when views are attached and detached. How nicely would this play with view recycling?

Scrolling from page "1", to "2", a new view would be created (as both could be onscreen at the same time during the touch-down). Moving from page "2" to "3", the UICollectionView could successfully dequeue the view for page "1", but what happens now? Would I forcefully insert the view into view controller three like so?

id cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ident" forIndexPath:indexPath];
UIViewController *child_controller = [self controllerAtIndexPath:indexPath];
[child_controller setView:cell];
// ... and so on

This feels wrong. However, I can't think of a correct way to reuse views correctly in this instance. Am I taking the wrong approach entirely?

like image 732
Sedate Alien Avatar asked Jun 20 '13 03:06

Sedate Alien


People also ask

What is the difference between ViewController and UIViewController?

UIViewController gives you an empty view, and you probably need some buttons, images, views etc. in it, to make the UI you need for your app. ViewController is there to make it easier to quickly create a simple app and to give people new to iOS programming an easier start in their project.

What is a UIViewController?

A UIViewController is an object which manages the view hierarchy of the UIKit application. The UIViewController defines the shared behavior and properties for all types of ViewController that are used in the iOS application. The UIViewController class inherits the UIResponder class.

What is a UICollectionView?

An object that manages an ordered collection of data items and presents them using customizable layouts.

How is UICollectionView implemented?

Create a new iOS app project Add a CollectionView by pressing command shift L to open the storyboard widget window. Drag the collectionView onto the main view controller. Add constraints to the UICollectionView widget to ensure that the widget fills the screen on all devices.


3 Answers

I don't think that UICollectionView is the best choose for your task.
Like rob mayoff said: you can use UIPageViewController.
Another option can be using UIScrollView with 3 subviews (previous, current, next). And you will be able to easy manage it's position and scroll view offset to achieve effect that you want.
This is described in WWDC 2011 'Advanced Scrollview Techniques'. You can grab source code from there.

like image 67
Sergey Kuryanov Avatar answered Oct 12 '22 01:10

Sergey Kuryanov


I've done the same thing, but with two view controllers visible at once, and reorderable, so a collection view was the right choice.

It turned out that removing the previous view controller's view and adding a new one caused quite a performance hit on scrolling, with removing the view being the slowest method.

Reuse of cells only makes sense if the new use of the cell is similar, but different - e.g. you're changing the text of a label or putting a different image in an image view. If you're ripping out and replacing the whole view hierarchy, you're not really reusing the cell.

What I ended up doing was using new cells for each view controller that could be contained. In my case there was a limit on the number of cells meaning that there wasn't really a problem with memory consumption having that many view controllers in play at once.

So, in a nutshell - don't reuse cells. It's more expensive than keeping the old ones around. Scrolling down a hundred row table is different to scrolling across a few full screen views. But, given the fact yours are full screen, a scroll view might be a better option.

like image 21
jrturton Avatar answered Oct 12 '22 01:10

jrturton


It's probably better to use UIView subclasses (or UICollectionViewCell subclasses) instead of encapsulated UIViewControllers. The encapsulated UIViewControllers have to have knowledge of their parent view controller, which could cause problems with code maintainability.

Complexity doesn't automatically mean you should look at adopting UIViewController. UIViews can be quite complex as well. The role of a UIViewController is really to provide additional encapsulation and lifecycle that it doesn't sound like you need here.

As other's have said, UIPageViewController seems like a good alternative too, but I don't know the specifics of your situation.

like image 44
Colin Cornaby Avatar answered Oct 12 '22 01:10

Colin Cornaby