Objective C: Change table cell configuration based on previous/next cell - iphone

Is there any way to change something about a table cell on the iPhone based on the previous or next table cell before that cell is displayed? This might be confusing, so here's an example:
Let's say I have a table like this (I'm just going to fill it with random values, so don't worry about the text contained in the cells):
*Cat
*Rabbit
*Dog
*Mouse
and there was a imageView.image attached to some cells (different images for different animals and you don't know which ones might have images) and at some point (programmatically) new animals are entered into the list sandwiching the animals that are already entered like so:
*[animal]
*Cat
*[animal]
*Rabbit
*[animal]
*Dog
*[animal]
*Mouse
*[animal]
How would I go about moving the images associated with the previously listed animals?
Hopefully you get a kick out of how ridiculous this question sounds, but I swear it is a serious question that is driving me insane and I didn't know how else to describe it.

Felixs' answer probably works, but it sounds like you are thinking of it from view-manipulation angle, and not a model-manipulation angle. It sounds like you really have two parallel models: the list of animals and the set of images. Why not just reloadData when either thing changes and rebuild the cells appropriately from inside your controller?
Reaching into existing cells based on their index feels fragile to me.

I hope I've got the right end of the stick here, but: In the cellForRowAtIndexPath: method, you could get a pointer to the previous cell (and so any associated images, text, etc.):
NSIndexPath *indexPathForPreviousCell=[NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
UITableViewCell *previousCell=[tableView cellForRowAtIndexPath:indexPathForPreviousCell];
I hope this is what you needed...

Related

Large UICollectionViewCell's disappearing with custom layout

I subclassed UICollectionViewLayout. So far, so good.
However, I have some cells that are wider than the screen, and sometimes these disappear while scrolling. When you scroll some more, they magically reappear where they should be. I can show you my code, however I think there's nothing wrong with it since it works in 90% of the cases.. However, really large cells (more than two times the screen size) disappear sometimes.
NSMutableArray* attributes = [NSMutableArray array];
for (int section=0; section < [[self collectionView] numberOfSections]; section++) {
[attributes addObject:[self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]]];
for (int row=0; row < [[self collectionView] numberOfItemsInSection:section]; row++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForItem:row inSection:section];
[attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
}
}
return attributes;
I've also these posts: UICollectionView's cell disappearing and Large cells in a UICollectionView getting removed while the cell is still displayed
However, a solution isn't mentioned. Can anybody help me with this? Could it be the problem is on Apple's side? And if it is, is there anything I can do to solve it myself?
Sorry to tell you: I'm pretty sure this a real bug in UICollectionView; I've run into this exact same thing a few weeks ago. I've made a small program to demonstrate the bug and filed a RADAR with Apple, but haven't heard back on whether or if they plan on fixing it. The best workaround I can think of (Warning: I haven't yet implemented this workaround) is to notice that the layout attributes are very far off the edges of the screen, intentionally change the bounds of the cell attributes so it only slightly goes off screen, and possibly store that offset (the amount that you trimmed off of what the real bounds should be) as an additional custom field in the layoutAttributes, so your cell knows to draw it's content correctly. Which feels like a gross hack, but it ought to work.
Are you sure you return the right attribute object for this cell when method -(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect is called and when the rect is just a part of your cell ?

constant tableviewcell at the beginning of the tableview

I would like to know if there is any sneaky way of getting a UITableViewCell to appear at the beginning of a UITableView no matter what the array that is going to populate the tableview contains?
I am having issues where I would like to have a "select all" cell at the top of the tableview but currently having issues trying to adjust the arrays I have going into the tableView:cellForRowAtIndexPath:
Not sure of your end goal, but there are many ways some easier (sneaky ways) than others depending on your needs. It sounds like your items are fairly static, so you can just insert them before you display or update the table row.
say you have a datasource called self.items and you did something to get data. Maybe in your app you are round tripping to some data source based upon input, like sort selectors or from the search bar delegate.
try something like this in the area where you load your datasource.
NSString *myCustomObject = #"Jump To Songs";
self.items = [self getGetMovieList];
[self.items insertObject:myCustomObject atIndex:0];
[self.tableView reloadData];
Another easy way would be to add sections to your table and just make the first section your navigation items.
Note: you may need to handle the actions in didSelectRowAtIndexPath......
there you go, not so sneaky, but pretty simple.
be well
You can make two types of UITableViewCell, then return the "select all" one if indexPath.row == 0.
On the other hand, how about just make a UIView for the "select all" functionality, and set it as the tableHeaderView of your table view?

Saving and loading state of tableview

I have a tableview where the user can make sections of people using a slider. So each section can have any number of people. I want to save the state of that tableview and then reload it when they come back.
I figured that since I'm using core data I can give each person a row and section attribute. So I'm able to save that but I don't know the best way to use those values to fill the tableview when it reappears.
I don't think that NSUserDefaults would work the best because I have many groups that can be broken into sections. I've been struggling with the best way to do this for a few days now and I'm still not sure what way to go.
More (per mihir mehta):
// Set core data values
int sec = 0;
int row = 0;
for (NSArray *section in groupsArray) {
for (People *person in section) {
[person setSubgroupSection:[NSNumber numberWithInt:sec]];
[person setSubgroupRow:[NSNumber numberWithInt:row]];
row++;
}
sec++;
row = 0; // new section so restart the row count
}
If you are already familiar with CoreData then perhaps you should stick with the plan you describe. The way I see it you should make some kind of TableViewInfoManagedObject:NSManagedObject. This TableViewInfoManagedObject should have members like #dynamic numberOfSections for example that describe what you need for your table view to work.
If you use CoreData to manage the people already consider using relationships to map numberOfSections to numberOfGroups or whatever you have in your People:NSManagedObject.
Also you need to consider when the appropriate time to "save" your state, which seems to be completely determined by the slider. In that case you may want to implement an IBAction for valueChanged.
EDIT 0: Based on the snippet you have provided it seems like at the end of the loop you would have the requisite info you need. The final value of sec should correspond to the UITableViewDataSource delegate method -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView and I am not really sure why you are setting the row number of the People object unless you are trying to achieve some sort order, which should be accomplished anyway by an NSSortDescriptor. So tableView:numberOfRowsInSection should return something like [[peopleinSection: section] count] and your tableView:cellForRowAtIndexPath should be set up so that it returns a cell like cell.textLabel.text = [[[peopleInSection:indexPath.section] objectAtIndex:indexPath.row] getPersonName]. Makes sense?
How about creating a class (subclass of NSObject) for each object that you need to save, and in that class you can add properties for each object. Then, you can use NSKeyedArchiver/Unarchiver to save and load your objects back to reuse.
Make a function that will take row and Section as argument and Returns that particular person by searching the array .... Got my point ?

Design cell make UITableView slow

Here is my problematique: I design my cell in my UItableView, so I added a title, a little description and an image.
All thoses element are store in my database, so in my UIViewController I calculate every position to have a nice cell, if there is no image in a cell I change the position of the title and the little description.
To check if the image is present or not I do something like that:
if ([fiche linkImg]!=#"") { //draw position of element }
or
if ([fiche.linkImg length] > 0 ) { //draw position of element }
My problem is when I begin to slide in my tableview its very slow and often very often crash, and the error are sometimes:
[CALayerArray listImg]
or
[NSCFArray listImg]:
Any idea?
Your description is a tiny bit confusing to see what is the problem.
I would suggest having a look at how to accomplish adding custom stuff to cell.
Have a read of apple's doc on UITableView especially a closer look at Table-View cells, if you scroll down in that section you will find examples of exactly the type of cells you are trying to create (text with pictures).
Try adding like this
if([fiche linkImg]!=nil)
I tried and succeeded

Best (Any) way blend tableview section header onto top of a grouped tableview

I'd like to add section headers to my grouped table view's sections but I'd like them to appear seamless (see image). The default, as we're all well aware of, is rounded top corners on the first row of a grouped table view cell so it ends up looking like crap when you merge them.
Any way to specify when indexPath.row = 0 that the UITableViewCell should use row style "middle" or something like that?
If not then what are my options? I guess I could scratch the section header and use Row 0 as a quasi-header then push my array data +1 to fill the rest of the table? I'd rather not roll my own from scratch...if possible.
Sample Table http://img35.imageshack.us/img35/8181/sampletable.png
Edit:
"Crap" looks like this:
alt text http://img25.imageshack.us/img25/9748/crapsection.png
Don't do what you're doing, it's against HIG
Ok, ok, I'll tell you how to do it:
You're going to want to do your own cell background views. The default grouped one is not what you want.
When a tableview asks you for a cell, set its backgroundView and selectedBackgroundView to something that looks appropriate for its place in the tableview.
Usually, this means a UIImageView with the appropriate image, though you can go wild here with a custom view, but there are gotchas.
So in your case, you would do
if (indexPath.row > sectionRowCount - 1) {
//Not the last row
//Put in the middle background
} else {
//Put in the end background
}
Then you'll want a custom table section header, but that's pretty easy.
In your case, you probably won't have to worry about when there's just one row, so that makes things even easier.
Take a look at the tutorial here:
cocoa with love basically what you need is 3 different images. One for the top row, one for the bottom, and a 3rd for the middle rows.
You could also not use the section header, but instead use a custom cell as the first cell of the section. So when ([indexPath row] == 0), return a custom cell that is the "header" and then return the "regular" cells (offset by one row) for the rest. You'll also have to make adjustments to the numberOfRowsInSection function to return +1.