I need to create a universal app with a listing. And on clicking a cell it shows the detail view of the cell. I have created the listing for a iPad by using a UICollectionView inside a UIViewController. But when I try the same in iPhone it doesn't show properly. Its kind of a zoomed version of iPad cell.
For iPad I need the cell to be like this
http://i.stack.imgur.com/8mJnI.png
And for iPhone I need the cell to be like this
http://i.stack.imgur.com/moUxm.png
What is the best way to do this?
Any help will be appreciated
UICollectionView is the model for displaying multidimensional data — it was introduced just a year or two ago with iOS 6, I believe. The main difference between the two is how you want to display 1000 items. UITableViewhas a couple of styles of cells stacked one over the other.
Select the Main storyboard from the file browser. 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.
This method asks the data source object to provide a supplementary view to display in the collection view. It asks the datasource object whether the specified item can be moved to another location in the collectionview. This method moves the specified item to the specified indexpath.
A layout object that organizes items into a grid with optional header and footer views for each section.
I would suggest create to abstract subclass of UICollectionViewCell with properties like image, title, desc and two subclasses of the abstract class, for example iPadCell and iPhoneCell.
In the storyboard add two prototype cells and change it class and identifier to iPhoneCell and iPadCell.
Layout the cell as you need and in collectionView:cellForItemAtIndexPath:
dequeue right cell, for appropriate device:
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
YourAbstractClass *cell = nil;
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
// Make sure it match storyboard identifier for iPad cell
cell = [cv dequeueReusableCellWithReuseIdentifier:@"iPadCellIdentifier" forIndexPath:indexPath];
}
else { //iPhone device
cell = [cv dequeueReusableCellWithReuseIdentifier:@"iPhoneCellIdentifier" forIndexPath:indexPath];
}
cell.imageView.image = ...;
cell.title = ...;
cell.description = ...;
return cell;
}
In very similar way you can set up cell size, if it's different for iPhone/ipad:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
return CGSizeMake(400.0f, 500.0f);
}
return CGSizeMake(200.0f, 300.0f)
}
since the content of you cell is same i.e.,
Instead of making a abstract class and then subclassing them, What you could also do is, you just make one custom class of UICollectionViewCell, for example name it as GenericCollectionViewCell, Now this class should have two nib files, and make sure you assign different reuse Identifier to both of them and different file name ofcourse, e.g.
So, now basically you have GenericCollectionViewCell.h with IBOutlets to two different nibs.
You will have to create a ENUM to in the GenericeCollectionViewCell e.g.
typedef NS_ENUM(NSUInteger, CellType) {
CELLIPHONE = 0,
CELLIPAD = 1
};
you will use this ENUM to initialise, What type of nib to use for this cell e.g.
+ (UINib*)cellNibForCellType:(CellType)cellType{
switch (cellType) {
case CELLIPHONE:
cellNib = [UINib nibWithNibName:@"IPhoneCollectionViewCell"
bundle:nil];
break;
case CELLIPAD:
cellNib = [UINib nibWithNibName:@"IPadCollectionViewCell"
bundle:nil];
break;
}
Once you have done that, you need to register this cell in viewDidLoad of your ViewController,
- (void)viewDidLoad
{
[super viewDidLoad];
[_collectionView registerNib:[GenericCollectionViewCell cellNibForCellType:CELLIPHONE] forCellWithReuseIdentifier:@"iPhoneCell"];
[_collectionView registerNib:[GenericCollectionViewCell cellNibForCellType:CELLIPAD] forCellWithReuseIdentifier:@"iPadCell"];
}
And then you could proceed with what, @Greg has explained above,
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
GenericCollectionViewCell *cell = nil;
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
// Make sure it match storyboard identifier for iPad cell
cell = [cv dequeueReusableCellWithReuseIdentifier:@"iPadCell" forIndexPath:indexPath];
}
else { //iPhone device
cell = [cv dequeueReusableCellWithReuseIdentifier:@"iPhoneCell" forIndexPath:indexPath];
}
cell.imageView.image = ...;
cell.title = ...;
cell.description = ...;
return cell;
}
Basically this is what I have come up with, if the content of the cells are same, what's the point of making super class, I mean I don't know I might be wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With