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.
Related
I have code:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 30;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:REUSE_IDENTIFIER forIndexPath:indexPath];
[[cell subviews]
makeObjectsPerformSelector:#selector(removeFromSuperview)];
[cell addSubview:someView];
return cell;
}
Above code gets executed in viewWillAppear
If I make the above code executed 30 times, the view appearance is really slow.
Due to cell reuse, I need to make a call to removeFromSuperView. Otherwise stale wrong data is displayed on the cell.
I am not able to figure out what could be causing the slowness??
Can you provide hints?
Your appearance is slow because you are iterating through all the subviews within the cell and removing from superview. This is a very expensive process and should not be done in the cellForItemAtIndexPath method of the collectionView data source/ Infact this should never be done. If you need to display relevant content you need to access the instance of the cell and update the properties of the UI elements within the cell.
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;
}
When creating cells for UICollectionView, dequeueReusableCellWithReuseIdentifier doesn't go through init nor initWithCoder function of CategoryView.
The view is creating, it has a proper type (CategoryView) but init nor initWithCoder of CategoryView is not called, so essential functionality is not executed. Is there some other init in this senario?
- (CategoryView *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CategoryView *cell = [cv dequeueReusableCellWithReuseIdentifier:#"CategoryView" forIndexPath:indexPath];
[cell someConfiguration];
return cell;
}
In this case, the problem was that the base class was not specified for your cell prototype in Interface Builder. So make sure the base class is set:
Then, when you call dequeueReusableCellWithReuseIdentifier, using the storyboard identifier you specified in the prototype cell, it calls initWithCoder when the cell is first instantiated. If the cell scrolls out of view and is later re-used for another NSIndexPath, the prepareForReuse is called:
#interface CategoryView : UICollectionViewCell
#end
#implementation CategoryView
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
NSLog(#"init");
}
return self;
}
- (void)prepareForReuse {
[super prepareForReuse];
NSLog(#"reuse");
}
#end
try - (instancetype)initWithFrame:(CGRect)frame
It works for me. I wrote UI programmatically.
Good luck!
UICollectionViews and UITableViews reuse cells to improve performance. initWithCoder: will only run once per reusable cell. As such, if you need something called every time a cell is displayed I would recommend writing a method as follows in your cellForRowAtIndexPath: method:
- (CategoryView *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CategoryView *cell = [cv dequeueReusableCellWithReuseIdentifier:#"CategoryView" forIndexPath:indexPath];
// self.parameters = an NSDictionary of the colors, text, etc. you need to the cell to know about
[cell configureWithParameters:self.parameters];
return cell;
}
Then, inside your configureWithParameters: method you can include colors, text, etc. that will help you setup your CategoryView.
You'll have to declare your configureWithParameters: method in your CateogryView.h as follows:
// CategoryView.h
- (void)configureCell:(NSDictionary *)parameters;
Then include your customizations in the .m as follows:
// CategoryView.m
- (void)configureCell:(NSDictionary *)parameters{
// Put Whatever initialization code you need here
// Example:
self.label.textColor = parameters["color"];
self.label.text = parameters["text"];
}
Make sure you have collection view delegate/datasource connected to your class.
Make sure you give base class for cell.
Make sure your cell has reuse identifier.
Make sure to register Nib for your reuse identifier. (You don't need to do that if your cell present in your collection view in storyboard).
And finally try changing
- (CategoryView *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
to
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Now your
- (instancetype)initWithCoder:(NSCoder *)aDecoder
Should be called.
Assuming you've subclassed UICollectionViewCell, you can put your initialization code in awakeFromNib().
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];
I am just a beginner. i want to display image which is stored in database in a collection view cell. I have already created database and collection view. my code is as follow,
MyDatabase *data;
data=[MyDatabase new];
imagearray=[data OpenMyDatabase:#"SELECT pic_name FROM exterior" :#"pic_name"];
so my question is how can i display images ? let me know the way/code
thanks in advance
You can use following code for display UIImage grid. Add UICollectionView for your xib file. Don't forget to set the delegate in collection.
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return noOfItem/ noOfSection;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
return noOfSection;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell =
[collectionView dequeueReusableCellWithReuseIdentifier:identifier
forIndexPath:indexPath];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [imageArray objectAtIndex:
(indexPath.section * noOfSection + indexPath.row)];
return cell;
}
In your xib file add UIImageView to your CollectionViewCell and change it tag value to 100.
Please go through below links.
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UICollectionView_class/Reference/Reference.html
Above link is from Apple developer site. It has all details of UIcollectionview and tutorials related it. Below URL is also having sample tutorial, which will help you a lot.
http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12
You have images array retrieved from database. Now it will act as data source for collection view. You need to form UICollectionViewCell which will have those images accordingly. Please study above links, you will get to know.