I am using a UICollectionView. Inside this View one of my cells has a size of 1000*600(showing one cell in screen).
In my UICollectionViewCell are 4 UILabels and two tableViews.
The data which I am passing to UILabels is not showing correctly and as soon as I scroll back the data does not retain. I have seen various example in which it was suggested to use block Operation.
Which approach I have to use? Please help.
Here is the code:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
ToursCollectionViewCell *collectionViewCell=[collectionView dequeueReusableCellWithReuseIdentifier:#"collectionViewCell" forIndexPath:indexPath ];
UILabel *artistOne=(UILabel*)[self.collectionView viewWithTag:1111];
artistOne.text=[artistNameOneArray objectAtIndex:indexPath.row];
UILabel *venueOne=(UILabel*)[self.collectionView viewWithTag:1212];
venueOne.text=[venueLocationOneArray objectAtIndex: indexPath.row];
UILabel *artistTwo=(UILabel*)[self.collectionView viewWithTag:2121];
artistTwo.text=[artistNameTwoArray objectAtIndex:indexPath.row];
UILabel *venueTwo=(UILabel*)[self.collectionView viewWithTag:2222];
venueTwo.text=[venueLocationTwoArray objectAtIndex:indexPath.row];
return collectionViewCell;
}
UILabel *artistOne=(UILabel*)[self.collectionView viewWithTag:1111];
should probably be
UILabel *artistOne=(UILabel*)[collectionViewCell viewWithTag:1111];
(and similarly for the other labels) because the labels are subviews of each
individual cell and not of the entire collection view.
Related
Without constraints my UICollectionViewCells load immediately without any problems at all. When I put constraints on in storyboard so the image view is horizontal and vertically centered to the cell, the first image cell does not load. I have to scroll a few times and then back to the beginning for the first image cell to show. Take the constraints off and it goes back to working perfectly fine.
I thought maybe the images weren't getting loaded in time but that doesn't appear to be the case.
What am I missing?
I can put in some code but it is a pretty standard UICollectionView with custom cell inside ViewController.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
NSString *imageName = [NSString stringWithFormat:#"%#", [self.urlArray objectAtIndex:indexPath.row]];
[cell setImageName:imageName];
[cell updateCell];
return cell;
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return self.collectionView.frame.size;
}
EDIT:
I just removed the navigation bar and the first 2 images were loading behind the nav bar. They are loading in the size of the default prototype CollectionViewCell. Once I scroll away and back to it, it is the expected size.
When you don't put in constraints, IB automatically puts in constraints for you that give you an absolute position and size based on the frame in the storyboard. Chances are good that the constraints you're adding are not doing what you think they are.
Adding [cell layoutIfNeeded]; right before return cell in cellforitematindexpath fixed it
I know how to reuse cells and I know how to not reuse cells, but that's not what I'm asking.
What I need is still reusing some cells but make it less frequent.
Let's say I've 10 cells presenting on the screen(each cell with animating GIF file in it, so setting up a cell is consuming), what the UICollectionView doing now is like allocate 10 blocks of memory for each of the cells that is being presented, and make reuse of the memory when new cells are coming. This has made the reuse too frequent, so it is setting up the cells all the time and has made the scrolling of the UICollectionView a bit slow.
Here is the code that I'm using:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ItemView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ITEM_VIEW_REUSE_ID forIndexPath:indexPath];
ItemData *itemData = [[_items objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
[cell setItemData:itemData];
return cell;
}
I'm thinking, is there a way that I can modify the internal reuse system. Like allocate 30 blocks of memory for each of the cells that is being presented and some cells that are not even presented, so it is not setting up the cells all the time, and I believe that will accelerate the performance of my app.
I want to start populating my UICollectionView with my cells at the middle and not at the very top. I am not sure if this bit of code will help, but I will post it just in case.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Cell *cell = (Cell*)[collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
NSMutableArray *data = [sections objectAtIndex:indexPath.section];
cell.cellImg.image = [data objectAtIndex:indexPath.item];
return cell;
}
Why not populate your array in another order? Take a look on Apple UICollectionViewDataSource Reference:
"You do not need to set the location of the cell inside the collection
view’s bounds. The collection view sets the location of each cell
automatically using the layout attributes provided by its layout
object."
If you need some more info about Collection View Layout:
UICollectionview Layout Tutorial
I've written an IOS App which uses UITableViewCells and I am converting it to use UICollectionView Cells.
It's working OK at present, but I can't figure out how to allow user to update a UITextFied which is situated within the UICollectionView Cell.
I've managed to do this with UITableView Cells.
I've searched for answers to my problem, but can't find anything that uses a UITextField within a UICollectionView Cell.
Help in pointing me in the right direction would be much appreiciated.
Can you show us some of the code you are using. I have used UITextFields in UICollectionViews without a problem, so I am not sure what your question is.
Edit:
First add a tag in storyboard or programatically to your textfield for this example we will use a tag of 2
Then every time you want to modify the textfield simply call
UITextField *myText = (UITextField *)[cell viewWithTag:2];
You can declare and IBOutlet for the UITextField and then get it lkike that:
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:some_index_path];
UITextField *myTextField = cell.textFieldOutlet;
Try this, It's work for me,
First you have to set tag to UITextFied
Add below line of code :-
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UITextField *addCaptionTxt=(UITextField *)[cell viewWithTag:101];
[cell addSubview:addCaptionTxt];
return cell;
}
I'm having some problems implemented dynamic row heights in a UITableView - but it isn't the cells that I'm having a problem with, its the UILabel inside of the cell.
The cell just contains a UILabel to display text. My tableView:heightForRowAtIndexPath: is correctly resizing each cell by calculating the height of the label that will be in it using NSString's sizeWithFont: method.
I have a subclass of UITableViewCell that just holds the UILabel property that is hooked up in storyboard. In storyboard I've set its lines to 0 so it will use as many lines as it needs, and I've set its lineBreak to Word Wrap.
Here is how I'm setting up the cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ExpandCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
SomeObject *object = self.tableObjects[index.row];
cell.myLabel.text = [object cellText];
[cell.myLabel sizeToFit];
return cell;
}
When I build this, I get my table view with the cell's all sized to the correct height for their content, but the labels are all 1 line that just runs off the side of the cells. However, if I scroll the table so cell's leave the screen, and then scroll back to them, their label will be resized correctly and the cell will look how I expected it to initially.
I have also attempted calculating the labels frame with the same method I'm calculating the row height with, and I get the same behavior - it doesn't draw correctly until it scrolls off of the screen and back on again.
I have found two ways to work around this, and neither are acceptable solutions.
First, if in viewDidAppear: I call reloadData on my tableview, the cells and labels draw themselves correctly the first time. This won't work for my situation because I will be adding and removing cells to this table, and I don't want to call reloadData every time a cell is added.
The second workaround seems very strange to me - if I leave the font settings at the default System Font 17 on the UILabel, the cells draw themselves correctly. As soon as I change the font size, it reverts to its behavior of not drawing a label correctly until it leaves the screen and comes back, or gets reloadData called on the tableView.
I'd appreciate any help with this one.
I ended up resolving this by alloc/init'ing the label in cellForRowAtIndexPath. I'm not entirely sure why this is a solution - but it appears the problem I was experiencing has to do with how storyboard (or when, perhaps?) creates the objects within the cell. If I alloc/init the label in the cell in cellForRowAtIndexPath, everything loads and sizes correctly.
So... my current fix is to check if the cell has my custom label in it. If it doesn't, I alloc/init the label and put it in the cell. If it does have one, as in its a cell that's been dequeued, then I just set the text in the label that is already there.
Not sure if its the best solution, but its working for now.
I ended up resolving this by unchecking the AutoSizing checkbox in IB. It is unclear why auto-layout was causing this problem.
I ran over the same problem and I end up solving it by calling [cell layoutIfNeeded] before return the cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ExpandCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
SomeObject *object = self.tableObjects[index.row];
cell.myLabel.text = [object cellText];
[cell layoutIfNeeded];
return cell; }