Remove unpopulated UITableViewCells? - objective-c

Working with TableViews and have a two-parted question:
I have a TableView where there are only four cells with content. However the TableView continues down with about five or six more, empty, cells. Is there a way of removing these? What this would do, graphically, is remove all the lines below these 4 cells, while everything else stays the same.
Regard the following image, it has 2 populated cells and 7 extra lines below them, I want theses lines removed:
2.The four cells contain buttons. Because of this I want to remove the users ability to click/mark the entire cell. Is there such a "setting"?
Thank you, Tobias Tovedal

1.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 4;
}
2.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

You have to set 0 to the size of your footer to clear those "ghost" cells.
self.myTable.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];

I am thinking of 2 ways to accomplish your first Q:
Set up TableView to be grouped and not plain (tableview will have round corners);
Make the separators color to match the background of the cells:
tableView.separatorColor = [UIColor whiteColor];// or whatever color you have
But you will have to manually add a line for each cells you are displaying.

Related

UITableView checkmark in some particular row in every section

I have a UITableView containing 'N' number of sections with 'N' no of rows in each section.
My requirement is:
When the table view page loads the 1st row in each section must be check-marked. The user then will have the option to select his choice in each section and that row in that particular section is check-marked.
How do I implement this functionality?
The information displayed in any particular row of a table is determined by the table's data source. Make sure that the data structure that you use for your data has some way of indicating that a given row has a check mark. Then just implement -tableView:cellForRowAtIndexPath: such that it determines whether a check mark should be displayed for the cell in question and adjusts the cell accordingly.
For example, let's say that the data is represented as an array of sections, and each section is an array of dictionaries. Each row, then, has its own dictionary. If a row is to have a check mark, its dictionary will have a checked entry set to YES; if it doesn't, that entry is NO. You can display the check mark as an image. Then you have:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyTableViewCell *cell = ... // code to get the cell
if (myData[indexPath.section][indexPath.row][#"checked"].boolValue == YES) {
cell.checkedImageView.image = self.checkmarkImage;
}
else {
cell.checkedImageView.image = nil;
}
return cell;
}
Putting the check mark in the first row of each section is just a matter of initializing your data so that the first entry in each section's array is checked and the others aren't.
You can change the checked cell by implementing -tableView:didSelectRowAtIndexPath: so that it scans through the array for the given section and unchecks any checked row, and then checks the selected row.
Of course, you don't have to represent your data using an array of arrays of dictionaries, and there's a good chance that you don't. That's fine -- the point here is just that you'll implement the functionality that you're after by implementing the table's delegate and data source such that they support the check mark, and that the presence or absence of the check mark in any particular row will be determined by some aspect of your table's data.
You can set your cell's accessoryType to a checkmark:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = ... // code to get the cell
// isCellSelectedAtIndexPath: is your custom method
// which encapsulates cell selection state logic
if ([self isCellSelectedAtIndexPath:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}

Insert rows with a custom cell into table view

In my tableView there is five rows that always exist in the table ,,, when I tap on one of them new three rows will appear under the tapped one.
If the first five rows is a default UITableViewCell ,,, I want the three cells also to be from another custom cell; so the main five cells will be different from the the secondary rows (three under the main cell).
Here is how I add the secondary rows :
In tableView delegate didSelectRowAtIndexPath :
NSInteger count = indexPath.row + 1;
NSMutableArray *newRows = [NSMutableArray array];//
self.expandedIndex = indexPath.row + 1;
self.tableExpanded = YES;
for(int i = 0; i < [self.numbers count]; i++)
{
NSIndexPath *path = [NSIndexPath indexPathForRow:count inSection:0];
[newRows addObject:path];
[self.myArray insertObject:[self.numbers objectAtIndex:i] atIndex:count];
count++;
}
[tableView insertRowsAtIndexPaths:newRows withRowAnimation:UITableViewRowAnimationTop];
The rows added but I want them to be from the custom cell that I want to create ,,, any ideas
This is what I would do. I would make newRows a property and then at the end of didSelectRowAt... I would call table refresh. Then in my cellForRowAtIndexPath check to see if the specific indexPath is in newRows, if it is use a different cell style:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if ([self.newRows contains:indexPath]) {
// create custom cell
} else {
// create normal cell
}
return cell;
}
If this does not make sense let me know and I can elaborate.
Also note, you will have some interesting edge cases to handle. For example, if the user clicks on the 3rd cell and new cells are inserted into rows 4-6, and they later click on cell 2, adding new cells in rows 3-5, then the previous 4-6 cells will now be at rows 7-9. I am not sure how you are you are structuring your app so this may not be an issue (like maybe on one of the five cells can have subcells added at a time) but just realize that this is a possibility.

UITableView in editing mode cell still selectable even when using

I have a UITableView that has AllowsMultipleSelectionDuringEditing set to YES. Selecting multiple rows is a big part of my app, and it works great.
The problem is, that on one of my tableView's I don't want the user to be able to select the first 2 rows when in editing mode, so I have implemented the following:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0 || indexPath.row ==1) {
return NO;
}//end
return YES;
}//end
This works how I thought it would, and doesn't show the red checkbox graphic or the option to re-sort the rows. BUT, I can still select those rows that are not editable, and call the indexPathsForSelectedRows method and return the indexPaths of those rows.
How can I prevent the user COMPLETELY from being able to select those rows while in editing mode, and prevent touches on those from being returned when calling indexPathsForSelectedRows? Why isn't canEditRowAtIndexPath: doing this for me?
One way to do this would be to implement – tableView:willSelectRowAtIndexPath: method and check if tableView.editing == YES then return nil for first two cells.
Something like,
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView.editing == YES && indexPath.row < 2 )
return nil;
return indexPath;
}
You can also set the selectionStyle of these two cells as UITableViewCellSelectionStyleNone in editing mode in cellForRowAtIndexPath method.
Did you try the following code?
tableView.allowsSelectionDuringEditing = NO;
or
tableView.allowsMultipleSelectionDuringEditing = NO;

Dynamic tableview cells creation

I have to make a tableview with different cells in it. I have three preferences and the table depends on them. There may be 6 different tableviews - 1 cell, 1cell and 3cell, no cell, 2 cell and 3 cell and so on, this depends on preferences
That's the best way to do this?
Maybe someone knows good example, or tutorial on this
You could make just one UITableView with different sections.
Based on your section id you may be returning different cell in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
indexPath contains row & section values.
Also you might return different number of rows in a section with:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//pass value to numper of cells;
return 4 (or) 2;
}
//use this to add cell
[tableview reloadData];

How to show multiple customcell and a custom section header in one uitableview?

I want to create a tableview like this. All sections have custom section header views.
The first row of first section contains a custom row rest of the first section cell's are another custom cell. Though every section will contain different type of cells.
So what is the best approach to achieve this while managing the speed of tableview? Currently I'm using custom cells using interface builder. Is there a way that I could add different things on different sections on cells?
Try to keep as few types of cells as you can. If one type cell is similar to another but with one or two extra labels, just set it all up in the same cell and keep the labels empty on the cell that doesn't need them. That way they can be in the same reuse queue. If the cells are different enough you might need to have more queues. Just instantiate them with a different cellIdentifier and they will get added to the queue for that identifier.
eg.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if(indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"firstRowCell"];
if(!cell) {
cell = [[UITableViewCell alloc] inittWithFrame:CGRectZero reuseIdentifier:#"firstRowCell"];
}
// -- first cell setup
} else {
cell = [tableView dequeueReusableCellWithIdentifier:#"genericRowCell"];
if(!cell) {
cell = [[UITableViewCell alloc] inittWithFrame:CGRectZero reuseIdentifier:#"genericRowCell"];
}
// -- generic cell setup
}
// -- common cell setup
return cell;
}