Is there any situation where using UICollectionViewController is appropriate compared to using UIViewController + UICollectionView? - ios

I am quite comfortable in using UICollectionView inside a UIViewController.
I have never used UICollectionViewController before.
I was wondering, is there any situation, where using UICollectionViewController is more appropriate?

In addition to the obvious -
setting your UICollectionView up for you
automatically marking conformation for necessary protocols like UICollectionViewDataSource & UICollectionViewDelegate
A UICollectionViewController gives you a few built in nice features that you otherwise have to do a lot of extra work to get right manually.
installsStandardGestureForInteractiveMovement
The default value of this property is true. When true, the collection view controller installs a standard gesture recognizer (based on a long-press gesture) to manage the reordering of views inside the collection view. The collection view’s data source must declare its support for reordering items by implementing the appropriate methods. Setting this property to false prevents the installation of this gesture recognizer.
useLayoutToLayoutNavigationTransitions
This property helps facilitate transitions between two or more collection view controllers using a navigation controller. When configuring your navigation controller, install a collection view controller as the root object on the navigation stack and set its value for this property to false. When the user selects an item that would require pushing a new collection view controller on the stack, set the value of this property for the new view controller to true. When you do that, the navigation controller performs an animated layout change between the contents of the two collection view controllers instead of the traditional push animation. Similarly, popping the topmost collection view controller off the stack animates back to the previous layout. The navigation controller drives the transition between the view controllers, including the ability to drive the transition interactively.
You must set the value of this property before pushing the collection view controller onto a navigation stack. Do not change the value of this property after the view controller is already on the navigation stack.
It's up to you if your case is a good candidate for using these features or not and based on that you can make the call.

UICollectionView inherits from UIScrollView (just another UIView)
UICollectionViewController inherits from UIViewController. and it implements some protocols. like UICollectionViewDelegate and UICollectionViewDataSource. it means everything is already done for you. and you just have to use it.. but as everything is already done for you. you may not be able to do some stuff. like resizing your collectionView.
if you want full control I recommend you to use your own UIViewController.. and add a UICollectionView as a subview.. so you can place it wherever you want and resize it.. don't forget to implement UICollectionView protocols for delegation and datasource.
You may change some properties with your View controllers. But when you use as part of its' controllers, you can't change it.
For example you Cant change UICollectionView Size of UICollectionViewController .

Related

IOS: What is the correct way to change a view from the class of a different view?

I have a UIImageView subclass (in swift) set up so I can access touchesBegan/touchesMoved/touchesEnded.
When one of these methods is called, I need to change a property of a different, loaded view.
It seems to me that I will now need to access the active view controller in order to set the properties of this other view. Is there are better way to go about this (such as event methods called in the view controller)?
Note that I'm new to iOS and I am not extremely familiar with the event system yet, as most information I've found is written in Objective C and not in Swift. (Don't worry, I'm looking through Apple's Documentation.)
Also, no, I can't change the UIImageView to a UIButton. Even if I changed to a UIButton, I need access to the individual touchesBegan, etc. methods and the same problem would persist.
If I'm understanding you correctly, you need to reference the UIViewController from the UIImageVIew to push/present a new UIViewController. You have a few options:
Fire an NSNotification from the image view and have an event listener on the view controller.
Create a delegate on the image view that fires a selector on the view controller.
Hold a reference to the view controller on the image view, and push a new view controller from the image view with that reference.
Modally present a new view controller on the application window's rootViewController.

Subclass UICollectionViewTransitionLayout for automatic UINavigationViewController transition animation

Is it possible to subclass UICollectionViewTransitionLayout to change the automatic (e.g. non-interactive) animation when pushing/popping a view controller onto/off a UINavigationController stack?
Apples documentation and some articles in the internet suggest it should be possible:
If you want to provide more than just a linear transition from the old to new layout over time, you need to subclass and provide the layout attributes for items yourself
…but I didn’t find a way yet.
I would like to use UICollectionViewController’s useLayoutToLayoutNavigationTransitions to push one collection view controller on top of another (using the same data source). The two view controllers use different subclasses of UICollectionViewLayout which I want to transition using custom UICollectionViewLayoutAttributes that need to be keyframed and modified by the transitionProgress.
I was hoping, just implementing collectionView:transitionLayoutForOldLayout:newLayout: would do the trick, but that method only is called when transitioning interactively.
The best way I could come up with for the pushing is to call startInteractiveTransitionToCollectionViewLayout:completion: on the UICollectionView and pushing the new view controller without animation in the completion handler. For popping the view controller I would hook into -viewWillDisappear: of the view controller and check for the current view controller in the stack; if it is not there, I could again perform startInteractiveTransitionToCollectionViewLayout:completion:
Somehow I guess there is a better way…

Changing a Table View Controller to a View Controller

I have a Table View Controller that displays information using JSON. I want to change the styling of my app, and I don't want it to have that "table" view that it has now. Whats the easiest way to change my Table View Controller to a regular View Controller, the biggest problem I have is that the code uses a tableView and I dont know how to get it to work as a regular view controller.
I using a Storyboard with a TableViewController thats linked to a controller called UpcomingReleasesViewController.
I want my app:
To look like this:
My original answer was assuming you just wanted to convert from a UITableViewController to a UIViewController. Looking at your screen snapshots, I infer you really want to switch from a UITableViewController to a UICollectionViewController (which is an iOS 6 feature than allows you to do precisely what you want).
In that case, change your base class to UICollectionViewController, and replace your UITableViewDataSource methods with UICollectionViewDataSource methods. And then redesign your scene using a Collection View Controller.
See the Collection View Programming Guide for more information. Or see WWDC 2012 sessions Introducing Collection Views or Advanced Collection Views and Building Custom Layouts.
If you need to support iOS versions prior to 6, then you have to do this collection view style coding yourself manually, putting your image views on a scroll view and using a standard UIViewController. It require more effort than using a collection view, but can be done.
Original answer:
If this view controller will have a table view on it, but you just want to add more controls to the scene? If so, just change the view controller's base class from UITableViewController to UIViewController, create the new scene, add a table view to it, and specify the table view's delegate and data source to be the view controller:
Also, make sure you define an IBOutlet for your table view (and if you call it tableView, that will minimize any coding changes needed).
If you do that, you can quickly convert a UITableViewController based controller to a UIViewController with minimal code changes.
If you're looking to make something like your new UI mockup, look into UICollectionView. You'll see many of the same concepts (i.e. dataSource, delegate method signatures are similar) that are used in UITableViews used in the collectionView API.

iOS VIewController for UIScrollViews content

I have a UIScrollView in my app and I am adding some custom views from xib to it so you can horizontally scroll (tabbing) in ScrollView to change which one is shown. For now this works but I have a problem with connecting views to controllers.
I don't know how to choose structure of ViewControllers (how many controllers should I use, use nested controllers,...).
I have a rootView and its controller. In this rootView there is a ScrollView and this ScrollView contains some custom views (subviews) loaded from xib (using loadNibNamed method).
My question is should I use the same ViewController as for rootView also for these subviews in ScrollView? Problem is that the ViewControllers view property is already bind to the rootView (super view in rootView) so when I bind this view property also to subviews an error is occurred. Also if I create new controller for these subviews an error is occurred as well.
When I am loading subviews to the ScrollView with loadNibNamed method in ViewController of rootView, owner of these subviews is ViewController (owner argument of loadNibNamed method is set to self).
Can you tell me please, how should I solve this? What controller should I use for subviews, should I create new one or should I use existing one. Or should I use some nested controller? I am newbie in iOS development so I have a chaos in using ViewControllers right now...
If there isn't much code that is relative to controlling the sub views you could use just the root view controller. i.e A single controller for a single scene would be a good MVC approach.
If you are using it this way , don't change the view property of view controller as this messes it up for the root view - controller setup. If you just need a reference to this views you already have it with the return value of loadNibNamed. Also if you are setting the owner to self then create additional instance variable to hold the sub views(and not the view property) so that you can specify the owner from the xib itself and connect the references appropriately.
However if you have substantial business logic to be written regarding the sub views then its fine to create separate view-controllers(a single class would be fine if all the subviews behave the more or less same way if you are getting what i mean) for it. In the xib for the subviews, you can specify this class as the owner and when using loadNibNamed: you should create an object of the subviewcontroller class and specify this as the owner. This way you can modularize the whole thing.

only one section header

I'd like to have the section header (for an UITableView) for the uppermost cell only , a sort of header for the table that sticks to the top, showing some additional information about the uppermost cell.
is it somehow possible? if not (as I suppose since I've carefully read all the documentation) do you have any idea how to replicate this behaviour?
You need to create your own view to use as the header. It will be simplest to make your custom header view be a sibling of the table view, and position it so that it's above the table view on the screen.
Since UITableView is a subclass of UIScrollView, your table view's delegate is also a scroll view delegate and receives the UIScrollViewDelegate messages. You want to implement this method:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
Each time your delegate receives that message, you want it to look at which table view row is at the top of the table view (using [tableView indexPathForRowAtPoint:tableView.contentOffset]) and update the contents of your custom header view accordingly.
Read the Apple documentation for UITableView. The property you're looking for is tableHeaderView.
This is hard (not impossible) with UITableViewController because it forces the tableView to be the root view.
If you implement your own controller, inherit from UIViewController instead of UITableViewController.
You must adopt the data source and delegate protocols, and implement the methods appropriately, but then you have a normal view as your root view. You can then add a UITableView in any location and size you want, with anything you want around it.
The only real restriction is static table views you build in IB. However, in that case, you can implement view controller containment, and just parent your table view controller into another controller, and give it a specific view to take over.
The first option is dead simple, but the second is an advanced technique, and you need to understand view controller containment to do it right.

Resources