I'm working with table view and sections...In some case I need do remove one section, in another set it back. I can do that in 2 ways:
1)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (somecase) {
return 2;
} else {
return 3;
}
}
and than
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *tableViewCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil];
[tableViewCell autorelease];
tableViewCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if (sectionNumber == 3 {
switch (indexPath.section) {
case 0:
break;
case 1:
break;
case 2:
break;
}
} else if (sectionNumber == 2) {
switch (indexPath.section) {
case 0:
break;
case 1:
break;
}
return tableViewCell;
}
}
And a second way is to implement
[self.tableView beginUpdates];
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:NO];
[self.tableView endUpdates];
But it's not working...I put this methods to ViewDidLoad, is that ok ? Or I should put in somewhere else ? Or what is the problem ?
And what is the best practice for removing section ? first one or second ? thanks....
set condition that will satisfy "somecase " then reload tableview
[tableview reloadData];
Related
I have a UITableViewController,with its own tableview.
But I still want to have another UITableView whose Data Source And Delegate are in another Class.
the symptom is: iPhone 4.0 can't show the UITableView , while The iPhone 6.0 Simulator can show this UITableView in a visiable and right way.
NSLog told me UITableView's height is 0.0 when on iPhone.
The Problem is : I will get the second UITableView by
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
and
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;`
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
doesn't have any response...
You can try this.
Create two objects for UITableView.
numberOfRowsInSection part do this
(NSInteger)tableView:(UITableView *)tblView
numberOfRowsInSection:(NSInteger)section {
if(tableView == tblLog)
return 3; //Or whatever value
else
return 2;
}
CELLFORROWATINDEX part do this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UILabel *headingLabel;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
cell.backgroundColor = [UIColor whiteColor];
}
if(tableView == tblLog)
{
switch (indexPath.row)
{
case 0:
{
//do something
} break;
case 1:
{
//do something
} break;
}
}
else if (tableView == tblRange)
{
switch (indexPath.row)
{
case 0:
{
//do something
}break;
case 1:
{
//do something
}break;
}
}
return cell;
}
Let me know if that helps
I am creating an "add new item" row to a section in a table view which gets dynamically added/deleted as the editing mode is entered/exited. This works fine however if the table is longer than the screen then the labels for any rows not yet displayed are not shown when you scroll down to see the new "add new item row".
The key parts of my code are:
setEditing...
-(void)setEditing:(BOOL)editing animated:(BOOL)animate
{
[super setEditing:editing animated:animate];
[self.tableView setEditing:editing animated:animate];
NSArray *paths = [NSArray arrayWithObject:
[NSIndexPath indexPathForRow:[self.location.rooms count] inSection:kSectionRooms]];
if (editing)
{
[[self tableView] insertRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationTop];
}
else {
[[self tableView] deleteRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationTop];
}
}
numberOfRowsInSection...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch (section) {
case kSectionFields:
return NUM_SECTION_FIELDS_ROWS;
break;
case kSectionRooms:
return [location.rooms count] + ([self.tableView isEditing] ? 1 : 0);
break;
default:
return 0;
break;
}
return 0;
}
portion of cellForRowAtIndexPath
if ([self.tableView isEditing] && row == location.rooms.count)
{
roomCell.textLabel.text = #"Add new room...";
}
else
{
roomCell.textLabel.text = [[loc.rooms objectAtIndex:row] name];
}
editingStyleForRowAtIndexPath....
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
switch ([indexPath section])
{
case kSectionFields:
return UITableViewCellEditingStyleNone;
break;
case kSectionRooms:
if ([indexPath row] == location.rooms.count && [self.tableView isEditing])
{
return UITableViewCellEditingStyleInsert;
}
else
{
return UITableViewCellEditingStyleDelete;
}
break;
}
return UITableViewCellEditingStyleNone;
}
These are all working correctly if there is no scrolling but as soon as there is scrolling then I get problems. I understand that this must be due to the fact that the TableView has not displayed the hidden rows and therefore has not gone through the lazy loading process. I've tried using reloadData but that makes no difference (unsurprisingly) but as I am new to this I am not sure of the best way of making the rows appear.
I am sure there will be a simple solution so any ideas would be most appreciated!
Cheers in advance
jez
Hi guys i have different section in my tableview ( more than 6) and each one has different rows. But only one of them leads to next view controllers
here is the code but when i click it its not working
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
switch (section)
{
case 5:
{
switch (row)
{
case 0:
{
Language_view_controller * language_controller = [Language_view_controller alloc];
[self.navigationController pushViewController:language_controller animated:YES];
[language_controller release];
}
break;
default:
break;
}
}
break;
default:
break;
}
}
You are just allocating the memory for your view controller, you also need to initialize it by doing something like this:
Language_view_controller * language_controller = [[Language_view_controller alloc] initWithNibName:#"Language_view_controller" bundle:nil];
[self.navigationController pushViewController:language_controller animated:YES];
[language_controller release];
I would a grouped tableview such that:
when the only row of the first section is associated to a state, say A, I can see only this first section with, possibly, some text under it (in a footer for example);
when this state changes, I would see other sections under the first;
How could I achieve this? Some code/link to obtain something similar?
Thanks,
Fran
No problem, just add some if else logic in all your tableView Datasource and delegate methods.
For example like this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (!canUseInAppPurchase || isLoading) {
return 1;
}
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (!canUseInAppPurchase || isLoading) {
return 1;
}
if (section == 0) {
// this will be the restore purchases cell
return 1;
}
return [self.products count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
cell = ...
NSString *cellText = nil;
if (!canUseInAppPurchase) {
cellText = #"Please activate inapp purchase";
}
else if (isLoading) {
cellText = #"Loading...";
}
else {
if (section == 0) {
cellText = #"Restore purchases";
}
else {
cellText = productName
}
}
cell.textLabel.text = cellText;
return cell;
}
and if you want to add or remove the second section you could use a simply [tableView reloadData]; or this smoother variant:
[self.tableView beginUpdates];
if (myStateBool) {
// activated .. show section 1 and 2
[self.tableView insertSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, 2)] withRowAnimation:UITableViewRowAnimationTop];
}
else {
// deactivated .. hide section 1 and 2
[self.tableView deleteSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, 2)] withRowAnimation:UITableViewRowAnimationBottom];
}
[self.tableView endUpdates];
be careful, you have to change the data in your datasource first. And this code will add 2 sections. But you can adopt it to your needs easily.
I have a very simple application with a UITableViewController. Upon EDITING, I am trying to slide a row into position 0 of the first section. The new row should have an INSERT editing style while the existing row should have a DELETE style.
I've overridden the following 4 methods:
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.editing && section == 0) {
return2;
}
return 1;
}
- (UITableViewCellEditingStyle)tableView:(UITableView*)tableView
editingStyleForRowAtIndexPath:(NSIndexPath*)indexPath {
int section = indexPath.section;
int row = indexPath.row;
if (self.editing && section == 0 && row == 0) {
return UITableViewCellEditingStyleInsert;
}
return UITableViewCellEditingStyleDelete;
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
NSIndexPath *ip = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView beginUpdates];
if (editing) {
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:ip]
withRowAnimation:UITableViewRowAnimationLeft];
} else {
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:ip]
withRowAnimation:UITableViewRowAnimationFade];
}
[self.tableView endUpdates];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"ClientsControllerCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc ] initWithStyle:UITableViewCellStyleValue1reuseIdentifier:CellIdentifier] autorelease];
}
int section = indexPath.section;
int row = indexPath.row;
if (self.editing && section == 0 && row == 0) {
cell.textLabel.text = #"Add Me";
cell.detailTextLabel.text = #"Detail text";
} else {
cell.textLabel.text = #"Test me";
cell.detailTextLabel.text = #"Detail text";
}
return cell;
}
But as soon as I go into EDIT mode, "both" cells end up with an editing style of UITableViewCellEditingStyleInsert.
If I change my logic and append the new cell to the END - then it correctly draws the cells with a DELETE style and the new cell get's an INSERT.
Either way, tableView:editingStyleForRowAtIndexPath gets invoked 4 times. In fact, if I insert the new cell into section:0 row:0, this method gets called with section:row 0:0, 0:1, 0:0, 0:0. Whereas if I append the new cell into section: row:1, this method gets called with section:row 0:0, 0:1, 0:0, 0:1.
What am I missing? I should be able to insert a row and catch it right? For some reason, I can't see section=0 row=1 come through a second time.
-Luther
There's another question on StackOverflow that appears to ask essentially the same thing: SO 1508066.
The answer there claims it's nonstandard to put the Insert row at the top; it should go at the bottom instead. I'm not sure I agree with that contention, but it's certainly the path of least resistance.