Custom Layout for custom cell design on UICollectionViewController - ios

I want to design a page like this image for Ipad:
I decide to implement it by UICollectionViewController, and I am going to use UICollectionViewController for the first time.
I want to know, UICollectionViewController let me have various layout for cells? and how can I do that?

Yes you can have different layouts for cells.
In your UICollectionView, you will need to register the various cell classes that you are going to use:
[self registerClass:[Class1 class] forCellWithReuseIdentifier:#"Class1"];
[self registerClass:[Class2 class] forCellWithReuseIdentifier:#"Class2"];
Then in your datasource delegate:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
//Whatever logic you will use to distinguish between the two classes
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Class1" forIndexPath:indexPath];
//OR
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Class2" forIndexPath:indexPath];

Related

UICollectionView cell does not showing

I have defined an UI for my App. There is a UICollectionView which is 100% defined in Main.StoryBoard. I have a fixed number of cells and each cell image has an image in it. I have setup the number of cell and image for each cell in Main.StoryBoard. However, when I launched the App, the UICollectionView is empty. It does not show any cell. What is wrong? Do I have to define a class for this UICollectionView? Do I have to write any ObjectiveC Code?
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 5; // put your array count
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell;
cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"GIVEYOURCELL_IDENTITIFER" forIndexPath:indexPath];// same identifier storyboard cell
UIImageView *thumbail = (UIImageView*) [cell viewWithTag:YOURCELLIMAGETAG]; // give tag here that you put in cell with imageview
thumbail.image = [UIImage imageNamed:#"ImageName"];// give your image here
return cell;
}
Main Point give UICollectionViewDataSource, UICollectionViewDelegate Delegates in your .h file and also from storyboard to your viewController.

load UICollectionViewCell to UIView

Im trying to load UICollectionViewCell from .xib, to the UICollectionView, which is in reusable UIView also in .xib. This UIView will be loaded to more UIViewControllers. I found out, that I need load cell like this:
[self.collectionView registerNib:[UINib nibWithNibName:#"MyCell" bundle:nil] forCellWithReuseIdentifier:#"CELL"];
but it will not load it.
I looked all around net for answer, but I couldn't find this specific case.
There are two different cases,
1) If you're using storyboards and custom cells.
2) Nib and simple UIView(hierarchy of UIViews).
Yours seems to be the second case,
First of all you need to make instance of a UICollectionView(by alloc init methods).
Then register the Nib holding your cell/view using following method.
[self.collectionView registerNib:[UINib nibWithNibName:CELL_IDENTIFIER bundle:nil] forCellWithReuseIdentifier:CELL_IDENTIFIER];
and then you can use that Nib using following method
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell;
cell = (UICollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:CELL_IDENTIFIER
forIndexPath:indexPath];
//Populate your data here.
return cell;
}
Hope this helps.. :)

Two different UICollectionViewCells, switch between them in a UISegmentedController

I wonder which's the easiest way to have two different UICollectionViewCells-identifiers in the same UICollectionView? I've got an UISegmentedController that I want to switch between to different styles of UICollectionViewCells.. Where to implement which code. I've got an PatternViewCell for the first Cell but how do i do with the other? Please advice!
You can have two collection view cell prototypes registered for a single cell class for a single collection view with a single data source.
First, in your storyboard, set Cell1 as a reuse identifier for the first cell prototype and Cell2 for the second one. Both of them should have PatternViewCell class.
Then, on changing value of your segmented control you reload your collection view:
- (IBAction)segmentedControlValueChanged:(id)sender {
[self.collectionView reloadData];
}
Bind this action to your segmented control for the Value Changed event.
Then in - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath method you can choose a reuse identifier depending on selected index.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = nil;
if (self.segmentedControl.selectedSegmentIndex == 0) {
identifier = #"Cell1";
} else {
identifier = #"Cell2";
}
PatternViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
//configure cell
return cell;
}

Which method should I use to do something between UICollectionViewCells?

I have implemented an UICollectionView image gallery. Each cell has some views and I would like to hide or show that views when I change the current cell, at least when the event starts. is there any method? or should I do something by delegate? I have paging enabled and custom cell and FlowLayout.
I have done everything almost like this tutorial
One way would be to keep the current selected cell index in a local variable in your viewController, and use that index to perform any actions when selecting another cell:
#property (nonatomic) NSIndexPath *selectedCellIndexPath;
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (![self.selectedCellIndexPath isEqual:indexPath]) {
UICollectionViewCell *lastSelectedCell = [collectionView cellForItemAtIndexPath:selectedIndexPath];
// Perform any change to lastSelectedCell before deselecting it
[collectionView deselectItemAtIndexPath:lastSelectedIndexPath animated:YES];
}
self.selectedCellIndexPath = indexPath;
UICollectionViewCell *selectedCell = [collectionView cellForItemAtIndexPath:indexPath];
// Change what you want in the newly selected cell;
}

UICollectionView with UITextView very slow

I have a UICollectionView, with custom UICollectionViewCell.
Every cell has a UITextView inside.
The problem: the UICollectionView is very slow, also in the simulator.
-(void)viewDidLoad
{
[self.collectionView registerClass:[AgendaCollectionCell class]
forCellWithReuseIdentifier:agendaCellIdentifier];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
AgendaCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:agendaCellIdentifier forIndexPath:indexPath];
cell.delegate = self;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
[cell setCurrentDateAtIndex:([indexPath row]) date:currentMonth events:events];
// Return the cell
return cell;
}
I checked the profiler
Every cell makes date-related computations.
As you can see, the loadNibNamed takes too much time to load. Also the UITextView takes too much.
I searched a lot of question here and used some of their answers.(I also cached all instances of NSCalendar). I do not understand why it takes about 435 ms to load. The UICollectionView has 40 cell (it contains the days of a month).
Should I abandon the use of UICollectionView and cast to a custom view by using drawRect?
EDIT
I think that a good point is that suggested in the answer: load the cell by using UNib and not registerClass. I can see a very big performance boost: from 400ms to just 98ms!
Try putting
UINib * nib = [UINib nibWithNibName:#"YourNibName" bundle:[NSBundle mainBundle]];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:#"MyCell"];
into your viewDidLoad and then never create the cells yourself (in the
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForIndexPath:(NSIndexPath *)indexPath;
implementation always call
UICollectionViewCell * cell = [collectionView dequeueCell...]
This way, I think, the collection view will only load the nib once (in your viewDidLoad method and then create copies of it when needed.

Resources