UITableView sections issue with different cell colors - iphone

I'm a newbie to iPhone development. I have a table view with multiple sections in it. I'm changing the color of cells like this and it works fine.
if ([indexpath row]%2)
{
trackCell.contentView.backgroundColor = [UIColor clearColor];
}
else
{
trackCell.contentView.backgroundColor = [UIColor colorWithRed:212/255.0 green:212/255.0 blue:212/255.0 alpha:0.1];
}
But now the last cell from one section has the same color as the first cell in the next section. How can I solve this?

This is pretty dirty, but you could count up all the cells before your current one and then use that count to work out the required color. This is untested, but something like the following should do it:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int cellCount = 0;
for (int i=0;i<indexPath.section-1;i++)
{
cellCount+=[self numberOfRowsInSection:i]
}
cellCount+=indexPath.row;
if(cellCount%2==0)
{
//set one color
}
else
{
//set other color
}
// blah
}

the problem is that if cell is in section 1 (or 2, 3, ...)
and the previous section has an odd number of cells, it ends with the same color of the last cell of previous cell.
so, you need to check the previous section number of cells, and if that number is odd, invert your "if" statement, and leave it as it is now if it is even
EDIT:
int toBeAdded = 0;
if (indexPath.section>0) {
toBeAdded = ([self tableView:tableView numberOfRowsInSection:(indexPath.section -1)]) %2 ;
}
if (([indexpath row]+toBeAdded)%2) {
trackCell.contentView.backgroundColor = [UIColor clearColor];
} else {
trackCell.contentView.backgroundColor = [UIColor colorWithRed:212/255.0 green:212/255.0 blue:212/255.0 alpha:0.1];
}
EDIT 2:
seeing "Will Jenkins"... he's right... you need to see all previous sections, not just the previous one...
his way to count all cells in a section is not so good and fast as mine, but his answer is the right one, +1 for him... anyway, the best way could be to combine his loop and my call to tableView:tableView numberOfRowsInSection:

Regaridng section change color, need to write your own logic like,
Need to use Static int value irrespective of sections and use already using code with replacing
indexpath.row with your value. i.e.
Static int Index;
if ( Index % 2)
{
trackCell.contentView.backgroundColor = [UIColor clearColor];
} else {
trackCell.contentView.backgroundColor = [UIColor colorWithRed:212/255.0 green:212/255.0 blue:212/255.0 alpha:0.1];
}
Index++;

It happens due to your Number of Rows in each section...
Suppose you are trying to provide RED color to Odd Rows and GREEN color to Even Rows and you have 3 rows in First Section then last cell will have RED color and First cell of Second Section also has RED color.
So you just need to check the number of rows in Previous Section. If it is Even Number then you should Maintain the Order of Color , otherwise simplly Change the Order of Color for the Section.

Related

Show previously selected cells by default when view opens, UICollectionView

I am creating a seat map, there are few seats already booked and others can be, So, i need to show the already booked seats and available seats by different colors. Below is my code i am using to show selected and deselected cells, but how to make show already booked cells selected already.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
NSLog(#"indexpath row:%d", indexPath.row);
int v;
NSString *cnt = [NSString stringWithFormat:#"%#",[arrSeats objectAtIndex:indexPath.section]];
v = [cnt intValue];
if(indexPath.item < v)
{
if(cell.selected){
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"yelow_seat.png"]]; // highlight selection
}
else
{
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"blue_seat.png"]]; // Default color
}
}else{
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"blank_seat.png"]];
}
return cell;
}
Below is the code i am trying to use to add values for each section. Each time array add values for a section it adds it into dictionary then clears the array and again next time the array add values for next section and and put to dictionary, but dictionary not holding the value when array objects removed.
arrStatus = arrSeatsStatus;
[seatsDict setObject:arrStatus forKey:[NSString stringWithFormat:#"%d",i]];
i++;
[arrSeatsStatus removeAllObjects];
I am having an array that holds the status of all seats as on or off, but how to implement it am not getting. Please guide for above.
Thanks in advance.
check this link for cell highlighting
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCellsandViews/CreatingCellsandViews.html
or do one this create a label or imageview for cell and do the checking whether the corresponding element is matching with your array element and then check their status ,if its matching then put some image or assign color over that item if its not matching leave it empty.
If it not working please let me i will help you

UITableViewCell Accessory Repeating?

In my app, I have a detailed view where the user can edit attributes of for example a person, their name, address etc.
In two cells, rather than being able to select them to edit their contents, they have a right accessory, a UISwitch, however sometimes, its inconsistent, but they replicate onto other cells in my last section.
I have been scanning my code dozens of times over with a fine comb and can't find the damn cause. What might cause this? Here is the code that I use to create the UISwitch on just a single cell:
if (indexPath.section == 0 && indexPath.row == 1)
{
cell.textLabel.text = #"Confirmed";
//Make the cell unselectable
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
//Create and add uiswitch
confirmedSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
[confirmedSwitch addTarget:self action:#selector(switchConfirmedStatus:) forControlEvents:UIControlEventValueChanged];
[confirmedSwitch setOn:[venue.isConfirmed boolValue]];
cell.accessoryView = confirmedSwitch;
}
So you expect it to only show up on that cell, see anything odd with that code? I have checked my if statements and all my brackets indexPath checks are correct.
Anyone see this before or have any clues?
The problem is because of reusability issues in the UITableView. You probably use the same identifier for all cells and this causes the cellForRowAtIndexPath to be implemented in other rows (when you scroll up and down).
This is a common problem when you are developing applications with tableView and there are plenty of questions like this on StackOverflow.
As a general solution, you will need to do either of these.
Use different identifiers when you assign dequeueReusableCellWithIdentifier for each cell. This is fairly simple, and you just need to assign different identifiers for them.
Subclass you UITableViewController, and create your own CustomTableViewController which will implement the necessary components in the cell. I believe you will need to override the set Layout Subviews method.
Take a array in view will appear and add object 0 for this row and 1 for all other rows and then in cellForRowAtIndexPath check if array has 0 at that index if it has then put switch otherwise nill..
for(int i =0;i<10;i++)
{
if(i==1)
{
[arrayForSwitch addObject:#"0"];
}
else
{
[arrayForSwitch addObject:#"1"];
}
}
then in cellForRowAtIndexPath write condition
if([arrayForSwitch objectAtIndex:indexPath.row isEqualToString:#"0"])
{
cell.accessoryView = confirmedSwitch;
}
else
{
cell.accessoryView =UITableViewCellAccessoryNone;
}
it will now remain same

When an UITableView is empty, show an UIImage

This is related to another question of mine which wasn't answered in a helpful way (message when a UITableView is empty).
I'm trying to show an UIImage graphic that says You haven't saved any bookmarks over an UITableView when it's empty. I have NSNotification set-up so that when bookmarks are added or deleted, a message is sent so that the UITableView can be updated.
I've been trying to do it with this code. Why won't this work?
- (void)bookmarksChanged:(NSNotification*)notification
{
[self.tableView reloadData];
UIImageView* emptyBookmarks = [[UIImageView alloc] initWithFrame:CGRectMake(75, 100, 160, 57)];
emptyBookmarks.alpha = 1;
emptyBookmarks.image = [UIImage imageNamed:#"emptyBookmark.png"];
[self.view addSubview:emptyBookmarks];
[emptyBookmarks release];
if ([self.dataModel bookmarksCount] == 0)
{
emptyBookmarks.alpha = 1;
}
else
{
emptyBookmarks.alpha = 0;
}
}
I'm probably approaching this the wrong way... But if salvageable, what am I doing wrong?
When I initially have an empty bookmarks tableview, there's no image displayed. After I add a bookmark and then delete it, the image shows. Grrh.
Another way (and IMO the correct way) to do this is to manipulate the backgroundView property on the UITableView.
While making a single cell with a custom image cell would certainly works, I think it overly complicates the logic of your UITableViewController's data source. It feels like a kludge.
According to UITableView documentation:
A table view’s background view is automatically resized to match the
size of the table view. This view is placed as a subview of the table
view behind all cells , header views, and footer views.
Assigning an opaque view to this property obscures the background color
set on the table view itself.
While you probably don't want to just set it to your UIImageView, it is very easy to make a UIView that contains the UIImageView that you want.
Well first off if you were going to do it that way, you would need to reload the tableView after updating the image or model etc. and not before.
But you are probably making things more complicated than they need to be!
Why not just check to see if the data for section 0 and indexPath.row 0 are empty and if so in cellForRowAtIndexPath display a text message accordingly.
// First make sure there is always one row returned even if the dataModel is empty.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger numRows = 0;
if ([self.dataModel lastObject]) {
// Return the number of rows in the section.
numRows = [self.dataModel count]; // etc.
}
if (numRows < 1) numRows = 1;
return numRows;
}
// Then display the data if there is some, otherwise a message if empty.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if ([self.dataModel lastObject]) {
// setup the cell the normal way here.
} else { // the datasource is empty - print a message
cell.textLabel.text = nil;
cell.detailTextLabel.text = NSLocalizedString(#"You haven't saved any bookmarks", #"");
cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.7];
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Are you sure [self.dataModel bookmarksCount] is equal to 0 ?
While I agree that you are probably going about this the wrong way,
your image is allocated and added in your bookmark changed, your notification does not trigger when there are no bookmarks initially. Hence you don't see the image. Call the bookmar changed when your table view inits or appears.
Probably the best way to achieve this is to perform a check in your numberOfRowsInSection method to return 1 if your data source is empty. Then in cellForRowAtIndexPath check if your data source is empty and if it is, create a custom cell that contains whatever you want. In heightForRowAtIndexPath you need to return your custom cell height if your datasource is empty, but only if you want the cell larger than the default. At least that is how I would approach it.
when bookmarks count is nil add one to your row method:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
int c;
c = bookmarks.count;
if(c == 0){
c = 1;
}
return c;
}
and then the same check again in your cellforrowatindexpath.
Another thing to be aware of in this situation is that if you're using core data and you're datasource is feeding off an entity, you will want to make sure your model matches. You can get some weird side-effect behavior in certain situations. This is especially true if you allow editing and core data has an empty model but you're tableview is still showing a cell.

Configuring UITableViewCell text dynamically

Here is my problem: I have UITableView and I want to dynamically configure "THE Cell" text with different text fonts e.g. first line will be 12, Helvetica, Bold and the second line will be 10, Helvetica. Also note that number of lines is unknown and needs to be dynamically determined. Any help appreciated!
ps: Apparently question isn't understood well. I didn't mean to show each line in different cells. So think about only one cell and configuring the text for this particular cell. I have a dynamically determined number of lines for this cell so it could be 2 or 3 depending on the availability of the information. And I want this lines to have different fonts and different colors. One way to go for this is to have dynamic number of UILabel for the cell, but I would like to see if there is other options?
I can't really answer this very well without an example pattern but here it goes:
In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath add your customisations. Here's some examples:
1)
if (indexPath = 1) { //row 1
cell.detailTextLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:12]; //Important note: -Bold can vary per font. For example, Arial's bold variant is 'Arial-BoldMT'.
//change to needs
}
else if (indexPath = 2) { //row 2
//etc.
2)
if (indexPath <= 6) { //row 1-6
cell.detailTextLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:12]; //Important note: -Bold can vary per font. For example, Arial's bold variant is 'Arial-BoldMT'.
//change to needs
}
else if (indexPath >=7 && indexPath <=15) { //rows 7-15
//etc.
3)
///etc.
else if (indexPath >=84) { //rows 84 and over
cell.detailTextLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:12];
}
Unless you have a specific pattern, it can be hard if you don't know how many rows there are. If you need any more help just comment below.
This is fairly trivial to do. Just set the content of the cells in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You can adjust the font size, color, etc based on the indexPath of the cell.
If you want a plethora of examples of what all is possible, then check out Apple's Table View Programming Guide.

UITableView Separator Style Question

I have a tableview that is blank by default. User can add cells to it.
I want the separator lines to be clear when there are no cells, and grey when there are cells.
I am using this code:
if ([[self.fetchedResultsController fetchedObjects] count] == 0)
{
self.routineTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.routineTableView.separatorColor = [UIColor clearColor];
}
else
{
self.routineTableView.separatorColor = [UIColor grayColor];
}
The problem is, when I launch the app with a blank table, and if I add cells, the grey lines are not there there until I restart the app. But if I start with cells there, then delete them, then re-add them, the lines are there. Any suggestions?
Maybe you are missing this?
...
else
{
self.routineTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; // or you have the previous 'None' style...
self.routineTableView.separatorColor = [UIColor grayColor];
}
EDIT :
You need this but not only this... According to Apple Documentation :
The value of this property is one of the separator-style constants described in UITableViewCell Class Reference class reference. UITableView uses this property to set the separator style on the cell returned from the delegate in tableView:cellForRowAtIndexPath:.
That means the style wont change for cells that are already loaded. Just scrolling the table to force cells to redraw should make separators appearing...
You then have to :
set it BEFORE cell is inserted
OR
reload tableView when the first cell is added
which is not easy to do with a NSFetchedResultsController, you should look into its delegate for a solution... or change direction, like hiding the tableView until you have a result maybe...
EDIT 2 : You can also simply add this :
[self.tableView reloadData];
but that's a dirty workaround that will just reload full tableView, losing most benefits of NSFetchedResultsController...
A quick fix I usually do is:
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([tableView respondsToSelector:#selector(setSeparatorStyle:)]) {
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
}
}
This changes the boolean flag of whether there will be a separator or not. Put this in viewDidLoad:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
And to make sure you've really made it go away, set the seperatorColor property to whatever the background color of the view and cell would be:
// If the background is white
self.tableView.separatorColor = [UIColor whiteColor];
So then even if somehow the above does not get called and the separator is still persisting - it would be the same color as what is behind it, therefore invisible.
Good luck.