I have managed to make the TableView expandable. The problem is that when I start the app, it's always opened. I want it to be closed, and to be opened just when I hit the row.
What am I missing here? How can I set it to be open at start?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!indexPath.row)
{
// first row
cell.textLabel.text = #"Expandable"; // only top row showing
}
else
{
cell.textLabel.text = #"Some Detail";
cell.accessoryView = nil;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canCollapseSection:(NSInteger)section
{
return YES;
}
You first create a regular table with some array of booleans that holds the state of each row (open/close).
Then, when you hit a first row in a section, I reload the table with new rows:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//subject hitted
if (indexPath.row == 0)
{
// set relevant boolean here ,also , reload the table again with the new rows
collapsedRows[indexPath.section]= ! collapsedRows[indexPath.section];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section]withRowAnimation:UITableViewRowAnimationFade];
}
//sub subject hitted
else
{
}
}
Related
I have implemented a Dynamic TableView, Textfield and Buttons. My problem is, when I hide the button in the first row of my UITableViewCell, the other five rows of cell button also get hidden.
Can any one suggest a solution for this issue?
I have tried below code..
ladiesdetails=[[NSMutableArray alloc]initWithObjects:#"2",#"0",#"0",#"0",#"0",#"0", nil];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 6;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell1";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[passengerdetailcell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if([[ladiesdetails objectAtIndex:indexPath.row] intValue]==2)
{
cell.malebutton.hidden=yes;
}
return cell;
}
Just put the else condition and make the button visible in cellForRowAtIndexPath method. If you have any other condition to show add that as well.
if([[ladiesdetails objectAtIndex:indexPath.row] intValue] == 2) {
cell.malebutton.hidden = YES;
} else {
cell.malebutton.hidden = NO;
}
like this
bool flag = ([[ladiesdetails objectAtIndex:indexPath.row] intValue] == 2)
cell.malebutton.hidden = flag
It happens because of cell reuse , you use allocate the cell like below one .
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 6;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
PassengerDetailTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"PassengerDetailCell" forIndexPath:indexPath];
if([[self.ladiesdetails objectAtIndex:indexPath.row] intValue]==2)
{
cell.maleButton.hidden = TRUE;
}
return cell;
}
I'm attaching an image because this is kinda hard to explain, I've also mocked up what I actually want it to look like. I'm going to try to explain it to so that others might find the question.
Maybe you've run up against this before and know a fix?
Here is the image of what I have alongside a mockup of what I want:
On the left, what I have, the items in the table are not separated by separator lines but the empty lines cells are separated. Ideally, the empty cells would not be shown and the table would just end letting the background show and the items in the table would have separators between their cells.
This is the corresponding code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
NSMutableArray *withoutThing = [NSMutableArray arrayWithArray:self.containerOfLists];
[withoutThing removeObjectAtIndex:indexPath.row];
self.containerOfLists = withoutThing;
[[NSUserDefaults standardUserDefaults] setObject:self.containerOfLists forKey:#"list of lists"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.tableView reloadData];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.containerOfLists count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = self.containerOfLists[indexPath.row];
return cell;
}
Ok.
In the Storyboard, select your UITableView, set the Separator to Single Line, or by code with:
[yourTableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
In your code, do somewhere:
[yourTableView setBackgroundColor:[UIColor lightGrayColor]];
Or the gray color you want.
Add this to your datasources methods (as the same level as tableView: cellForRowAtIndexPath):
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return [[UIView alloc] init];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5; //return correct number
}
in ViewDidLoad method call:
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
Init cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell)
{
//init the cell!
}
cell.textLabel.text = self.containerOfLists[indexPath.row];
return cell;
}
I have two sections in a TableView, having their respective sectionHeaders. numberOfRowsInSection is counted dynamically & it might also come out to be 0. So i want to display a default text somewhere in the section in case of 0 rows.
How do i do this ? (Working on iOS 6, XCode-4.2)
Why don't you display the default text in a cell in the "empty section"?
Instead of returning 0 rows return 1 and place the default text in there. It can be something like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Verify is the section should be empty or not
if(emptySection == NO) {
return numberOfRowsInSection;
}
else {
return 1;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if(emptySection && indexPath.row == 0) {
cell.textLabel.text = #"This is the default text";
}
else {
// Display the normal data
}
return cell;
}
Update
The following code will avoid any actions when tapping an a cell that contains the default text.
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(emptySection) {
return;
}
// Perform desired action here
}
Another solution is to completely prevent the cell from being selected:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)path
{
if(emptySection) {
retur nil;
}
return path;
}
im using core data i have an entity called questions whenever i add my question to my table i want them to display the number of the question (kind of like auto increment thing)
can anyone pls help me out
thanks
here is my code if its relevant
- (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 [self.questionArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
// Configure the cell...
questionObject = [self.questionArray objectAtIndex:indexPath.row];
cell.textLabel.text = questionObject.questionDescription;
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (nil == cell) {
cell = ...; //create a cell instance if it wasn't found in reusable cache
}
// Configure the cell...
questionObject = [self.questionArray objectAtIndex:indexPath.row];
NSString *cellText = [NSString stringWithFormat:#"%d. %#", indexPath.row+1, questionObject.questionDescription];
cell.textLabel.text = cellText;
return cell;
}
If I call reloadRowsAtIndexPaths for the first cell of a section, with previous section empty and the one above not-empty, I get a strange animation glitch (even if I specify "UITableViewRowAnimationNone") where the reloaded cell slides down from the above section..
I tried to simplify the example as much as possible:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0)
return 1;
else if (section == 1)
return 0;
else if (section == 2)
return 3;
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
cell.textLabel.text = #"Text";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *editedCell = [[NSArray alloc] initWithObjects:indexPath, nil];
//[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:editedCell withRowAnimation:UITableViewRowAnimationNone];
//[self.tableView endUpdates];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return #"Section";
}
Actually you can comment out the last method, but it gives a better understanding of the problem.
You can set values you want to the cell directly, not letting table to reload itself (and thus avoiding any unwanted animations). Also to make code clearer and avoid code duplication lets move cell setup to a separate method (so we'll be able to call it from different locations):
- (void) setupCell:(UITableViewCell*)cell forIndexPath:(NSIndexPath*)indexPath {
cell.textLabel.text = #"Text"; // Or any value depending on index path
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[self setupCell:cell forIndexPath:indexPath];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// create cell
// Configure the cell...
[self setupCell:cell forIndexPath:indexPath];
return cell;
}