3

What I want to accomplish:

I'm designing a simple game's main screen. On the bottom half of the screen I want it to contain a collection view presenting a list of levels to choose from (long list, horizontally scrollable, nothing fancy - so it may be handled by a standard flow layout). On the top half of the screen I want to have a bunch of static, non-scrollable elements like an image or a label with game title, a static button leading to the credits page, a text field to enter user name etc.

The problem:

As the focus of this design seems to center around a collection view, I'm trying to use a UICollectionViewController in my storyboard to handle this. However, when I drag UICollectionViewController into my storyboard, it seems to always occupy full screen. I can't find a way to shrink it down nor to drag & drop any button or labels onto it.

The question:

How can I accomplish such design as described above (collection view occupying only part of the screen, the other part being occupied by some static, non scrollable controls)?

Should I:

  1. provide static buttons inside flow layout's header or footer section? (but then I'd have to make them "sticky", so they don't scroll with the rest of the content
  2. subclass flow layout and implement static buttons as layout's decoration views
  3. create custom container controller with two sections, one with UICollectionViewController, second with a plain view controller with a bunch of static buttons
  4. Do not use UICollectionViewController, but instead use a plain UIViewController and handle collection data source and delegate "manually" (it seems as a lot of unnecessary work)
  5. maybe I just miss some simple way to drag&drop buttons over UICollectionViewController in XCode's IB (or to configure)
  6. any other way to do it?

Please note that: 1. I'm complete iOS newbie, may miss some very obvious solution 2. Apart of sharing the same screen all of my components are very standard, I don't need any custom layouts or behaviours for my collection view or buttons - so I'd like to know whats the cleanest and simplest way to do this (some of potential solutions I proposed above seem like they may work, but for me sound like an overkill to implement such a simple screen)

1 Answers1

1

I think you need something like in the following figure
enter image description here

The bottom view(Thumbnail view) is a UICollectionView created using UICollectionViewController.

What I did is

  1. Created a UICollectionViewController subclass and add its view(ie collectionView) as the sub view of the mainViewController.
  2. CollectionView is managed by its controller class. I named it as SlideViewController

SlideViewController.h

 #import <UIKit/UIKit.h>

 @interface SlideViewController : UICollectionViewController

 @end   

SlideViewController.m

 #import "SlideViewController.h"
 #import "CollectionViewCell.h"


 @implementation SlideViewController

 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
 {
   self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  if (self) {
    // Custom initialization
   }
return self;
}

-(id)init
{
  UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
  self = [super initWithCollectionViewLayout:layout];
   if (self) {
    layout.itemSize = CGSizeMake(100, 100);
    layout.sectionInset = UIEdgeInsetsMake(5, 10, 5, 10);
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
  }
 return self;
}

- (void)viewDidLoad
{
  [super viewDidLoad];
  self.view = self.collectionView;
//self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.collectionView.backgroundColor = [UIColor orangeColor];
[self.collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"cell"];

}  

How to use

In mainViewController

 self.slideViewController= [[[SlideViewController alloc]init]autorelease];
 self.slideViewController.view.frame = CGRectMake(20, 300, 280, 200);
 [self.view addSubview:self.slideViewController.collectionView];
Anil Varghese
  • 42,757
  • 9
  • 93
  • 110
  • Yes, exactly like on your picture - but with the assumption that the big picture on the top is completely static and disconnected from the thumbnails at the bottom (so it doesn't change when the thumbnails at the bottom are being scrolled, doesn't synchronize with them in any way etc.). –  Apr 26 '13 at 09:02
  • Imagine that this is a simple game - tapping on the small image in the scrolling collection at the bottom should invoke a segue presenting GamePlayViewController (with particular level selected - depending on which thumb is tapped) while tapping on the big picture at the top should invoke a different segue presenting e.g. CreditsViewController with a static information about the game author. –  Apr 26 '13 at 09:03
  • You should do it programmatically. The entire screen call it as mainViewContoller. It has two sub views one static image and a collectionView(sildeView). There is no connection between the slide view and static image. slideView is controlled by a collectionView controller. So the relation you have to make using delegates. Instead of using segues do it programmatically. What iam doing is when you select a cell in collectionView(you will get call on __didSelectItem__ of collectionView) iam calling a delegate method of the mainViewController that will make some effect on static image. – Anil Varghese Apr 26 '13 at 09:11
  • Static image and collectionView are distinct views controlled by two view controller communicating through delegates only. You can implement the same scenario in you game – Anil Varghese Apr 26 '13 at 09:13
  • Thanks for the detailed example! In general, this is the behaviour I need, however I have one more question: is there any way to do it (or at least some part of it) in IB instead of fully programmatically? (I'd like to be able to e.g edit the sizes of both interface parts in WYSIWYG mode etc.) –  Apr 26 '13 at 09:35
  • You can design everything in storyboard except that collectionView part. you can design MainViewController and GamePlayViewController in IB no problem. Adding collectionView you should do by code also presenting GamePlayViewController(cannot use segue just present it by code) . Designing in IB makes no problem except the collectionView. – Anil Varghese Apr 26 '13 at 09:50
  • yes, sure :) big thanks for help! one more thing: I've also found that you can size and position your contained controller using Container View in IB (it reduces the amount of code by a tiny bit) - see these answers: http://stackoverflow.com/questions/13355022/what-is-container-view-in-ios-5-sdk, http://stackoverflow.com/questions/13275112/xcode-storyboard-container-view-how-do-i-access-the-viewcontroller –  Apr 26 '13 at 11:10