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
Related
I have a method selectAll to select all my cells in my UITableView. This method check a checkbox (UIButton). It's work very well just for the "visible" cells but not for the "invisible" cells!
Here my method:
- (IBAction)selectAll:(id)sender {
for (NSInteger s = 0; s < self.tableView.numberOfSections; s++) {
for (NSInteger r = 0; r < [self.tableView numberOfRowsInSection:s]; r++) {
CustomCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:r inSection:s]];
if(!cell.checkbox.selected){
cell.checkbox.selected = !cell.checkbox.selected;
cell.account.checked = cell.checkbox.selected;
}
}
}
}
From the documentation:
cellForRowAtIndexPath:
Return Value:
An object representing a cell of the table or nil if the cell is not visible or indexPath is out of range.
You can create an array that contains a list of booleans for checked or unchecked, and interrogate it when the cell is visible.
You need to check or uncheck your "selected" or "checked" state of your cells in the "cellForRowAtIndexPath" method. The underlying data source is another place where you can keep track of what should be the state of the data you're trying to represent in the cells.
Simply modifying the UITableViewCells via this function is only going to update the cells that are currently visible within the table view.
Check it in cellForRowAtIndexPath. Just check the if condition with the suitable indexPath.section
if (indexPath.section== add the section){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
I am attempting to call a reloadData on my table's rows on a viewDidAppear method access. However, my cells are not refreshing their values and I cannot figure out why, as it seems everything is being accessed in the order it is suppose to. To make matters more odd, 1 row actually does refresh, but none of the others do.
Here is my code...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set up the cell...
static NSString *CellWithIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];
NSLog(#"generating cell contents");
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = [_tableGroup.options objectAtIndex:rowcount];
rowcount++;
//label for currently selected/saved setting
_currentSetting = [[UILabel alloc] initWithFrame:CGRectMake(160, 8, 115, 25)];
[_currentSetting setFont:[UIFont systemFontOfSize:14]];
_currentSetting.backgroundColor = [UIColor clearColor];
_currentSetting.textColor = [UIColor blueColor];
_currentSetting.textAlignment = NSTextAlignmentRight;
[cell.contentView addSubview:_currentSetting];
NSLog(#"added new label to cell");
}
//depending on the setting, set the label in the cell to what is currently selected
if (indexPath.section == 1 && indexPath.row == 0) {
_currentSetting.text = [NSString stringWithFormat:#"%# %#",[settings.mapDistance stringValue], NSLocalizedString(#"MILES_IDENTIFIER", nil)];
NSLog(#"setting map distance label: %#", settings.mapDistance);
}
else if(indexPath.section == 1 && indexPath.row == 1)
{
_currentSetting.text = [NSString stringWithFormat:#"%# %#",[settings.maxCustomers stringValue], NSLocalizedString(#"ITEMS_IDENTIFIER", nil)];
NSLog(#"setting max customers: %#", settings.maxCustomers);
}
else if(indexPath.section == 2)
{
_currentSetting.text = [NSString stringWithFormat:#"%# %#",[settings.maxProducts stringValue], NSLocalizedString(#"ITEMS_IDENTIFIER", nil)];
NSLog(#"setting max products: %#", settings.maxProducts);
}
return cell;
}
based on this code, i get this output with my NSLOGS.
this is the first run of the cells when the view is created. It generates 4 cells, puts labels in each cell, and in 3 of those labels, puts in a value.
generating cell contents
added new label to cell
generating cell contents
added new label to cell
setting map distance: 15
generating cell contents
added new label to cell
setting max customers: 250
generating cell contents
added new label to cell
setting max products: 150
at this point i have clicked a row, went to a different screen, and have now returned. as you can see, map distance is different. although no change is displayed, even though the code to change the label's text is accessed during the reload process.
reloading data
generating cell contents
generating cell contents
setting map distance: 25
generating cell contents
setting max customers: 250
generating cell contents
setting max products: 150
again, I'm at a loss because the last row DOES refresh correctly. But none of the others do.
Thanks
When you reload your tableView, the cells already exist and are dequeued from the tableView, so the condition if (cell == nil) returns false, and the cell creation code is not executed.
In that cell creation code, you are assigning a value to _currentSetting and then proceed with the acode assuming that value is correct. However, when the cell creation code is not executed, that value points to the latest created cell, and thus, it won't update.
To fix this: make _currentSetting a local variable and change the code to look like this:
(You don't really need to make it a local variable, but it's more appropriate because you don't really need a reference to the last label you created after you leave this method)
UILabel *_currentSetting = nil;
if (cell == nil) {
_currentSetting = ...
_currentSetting.tag = 123;
}
else
_currentSetting = [cell.contentView viewWithTag:123];
...
The problem here is that the second time (when you are reloading the view ) the _currentSetting is not having a valid memory .So it is better to implement a custom cell and do the job
Better refer this an excellent guide
The second time around, you can see that "added new label to cell" isn't being called, so you're re-using an old tableViewCell.
Note that you're not setting _currentSetting when re-using a cell, only when creating a new cell. So _currentSetting is set to the last new cell that was created, most likely the last cell in the table.
You need to make sure to set _currentSetting to the correct label (maybe by using viewWithTag: or something similar).
(e:f;b)
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.
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.
I'm getting a weird issue. I have a custom UITableViewCell and each cell has a UIButton and UITextField. When the button is clicked, it changes the textfield value to some constant.
Now in the cellForRowAtIndexPath method I have this:
folderTitleTextView.tag=indexPath.row;
[arrayOfTextFields insertObject:folderTitleTextView atIndex:indexPath.row];
NSLog(#"indexpath.row:%i", indexPath.row);
NSLog(#"text fields count %i", [arrayOfTextFields count]);
So if I have two cells, then every time I reload the table, it adds two more objects to the arrayofTextFields, even though it should replace the existing ones. So if I have two cells and I reload the table 3 times, then for some reason arrayOfTextFields count is 8.
This folderTitleTextView.tag=indexPath.row; is not a good idea because everything starts with a tag of 0, so when accessing views with viewWithTag:0 or when setting up the row 0, you will get weird results.
I would suggest also checking the number of items in arrayOfTextFields and use [arrayOfTextFields replaceObjectAtIndex:indexPath.row withObject:folderTitleTextView]; or [arrayOfTextFields insertObject:folderTitleTextView atIndex:indexPath.row]; depending on the current count for arrayOfTextFields
Try this:
folderTitleTextView.tag = (indexPath.row + 100);
if ([arrayOfTextFields count] <= indexPath.row) {
[arrayOfTextFields insertObject:folderTitleTextView atIndex:indexPath.row];
} else {
[arrayOfTextFields replaceObjectAtIndex:indexPath.row withObject:folderTitleTextView];
}
NSLog(#"indexpath.row:%i", indexPath.row);
NSLog(#"text fields count %i", [arrayOfTextFields count]);
The question is what are you trying to do?
Right now you add the textView to an array each time a cell is displayed.
If you have 1 cell you have 1 textView in the array because cellForRowAtIndexPath: was called 1 time.
If you add another cell so you have 2 total cell cellForRowAtIndexPath will be called another 2 times and it will add 2 textViews to the array that already has one -> 3
If you add another cell cellForRowAtIndexPath adds 3 more textViews to the 3 that are already there -> 6
So much for the explanation of your results.
My suggestion is to get rid of that array and get rid of the tag, most likely those are not needed at all.
you can access the cell with something like this:
- (IBAction)buttonPressed:(UIButton *)sender {
UIView *contentView = [sender superview];
UITableViewCell *cell = (UITableViewCell *)[contentView superview];
// you should assign a tag to the textField of your cell. Use the same tag for each textView in all cells.
UITextField *textField = (UITextField *)[cell viewWithTag:42];
textField.text = #"Foo";
}