The user can select/deselect cells in each section, so to track all the selected cells in the didSelectRowAtIndexPath is not useful:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"row = %i, section = %i", indexPath.row, indexPath.section);
}
What i want instead is to save time and resources, so to let the user check/uncheck whatever he wants, and when he click on a button (to go to next view), i need to collect all selected cells in the whole table view. I tried to do like this:
-(IBAction)nextView:(id)sender{
themesChoosed=[self.tView indexPathsForSelectedRows];//tView is the outlet of my UITableView and themesChosed is an NSArray declared in the .h file
for (int i=0; i<=[themesChoosed count]; i++) {
NSIndexPath *thisPath = [themesChoosed objectAtIndex:i];
NSLog(#"row = %i, section = %i", thisPath.row, thisPath.section);
}
}
But this doesn't return me the selected cells, it shows me always: row = 0, section = 0 as if i am only selecting the first cell in the first section.
Any thoughts on how to do so?
Take in .h file
NSMutableArray *selectedArray;
in .m
viewDidLoad
selectedArray=[[NSMutableArray alloc]init ];
in tableviewDidSelect
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//According to section take value from table and get string selectedString.
if([selectedArray containsObject:selectedString])
{
[selectedArray removeObject:selectedString];
}
else
{
[selectedArray addObject:selectedString];
}
}
Related
I have created expanded tableview using plist, I have populated all the values and images into my tableview. Here I want to make animation for my particular cell when user click that cell.
For example, first time images will be default, next time if I click that cell, the particular cell get expanded. Here I need to make my image has hide; again if user press it will show the image. How to do this?
Every time the user taps a cell, a UITableViewDelegate method gets called, and in this method you can reload the cell:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
When a cell is reloaded, the method below is called (between the others), and the only thing you have to do is to return a different height according with the current state of the cell:
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return (/* cell state */) ? 100.0 : 50.0;
}
You have multiple ways to store your cell's state, you can do it in its model for example.
There are other ways also, this is only a solution. But the key point is that you have to reload the cell, and return a different height according with the conditions you want to consider.
You can check my full solution in the following github
Here is some of my implementation.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
movies = [[NSArray alloc] initWithObjects:
(NSArray*)[[Section alloc ] init:#"Istanbul" movieNames:#[#"Uskudar", #"Sariyer"] isExpanded:false],
(NSArray*)[[Section alloc ] init:#"Bursa" movieNames:#[#"Osmangazi", #"Mudanya", #"Nilufer"]
isExpanded:false],
(NSArray*)[[Section alloc ] init:#"Antalya" movieNames:#[#"Alanya", #"Kas"] isExpanded:false], nil
];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return movies.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return ((Section*)movies[section]).movies.count ;
}
-(void)toggleSection:(ExpandableHeaderFoorterView *)headerView withSection:(int)section
{
((Section*)movies[section]).expanded = !((Section*)movies[section]).expanded;
[expandableTableView beginUpdates];
for (int i= 0; i< ((Section*)movies[section]).movies.count; i++)
{
NSArray* rowsToReload = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:i inSection:section], nil];
[expandableTableView reloadRowsAtIndexPaths:rowsToReload
withRowAnimation:UITableViewRowAnimationFade];
}
[expandableTableView endUpdates];
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
ExpandableHeaderFoorterView* headerView = [[ExpandableHeaderFoorterView alloc] initWithCustom:((Section*)movies[section]).genre withSection:(int)section withDelegate:self];
return (ExpandableHeaderFoorterView*)headerView;
}
http://www.iostute.com/2015/04/expandable-and-collapsable-tableview.html
You can see this tutorial. It's a very good tutorial based on expandable tableview cell.
Im making my first app. My app will have a side pop out menu. I have gotten the sliding menu part implemented with a UITableView. Now i want to populate the side menu with text and a image next to it and when one is tapped i want to push another view controller. What would be the best way to do this? Thanks
As user132490 said, you probably want to add rows to your tableView. Here's a tutorial: http://www.appcoda.com/uitableview-tutorial-storyboard-xcode5/. It's for Xcode 5 but still will work. You may find it useful from "Adding Table Data" and below. In fact, before the Summary the tutorial teaches you to add a thumbnail next to the text of each of your cells.
Good luck!
When you want to have an image and text for your table, you have to create a UITableViewCell subclass and declare an image view and label. Image view and label must be created in IB, create a prototype cell and add there the image view and label.
Once you've done that you must have an array of what will be the content of your table. It's like this:
In #interface:
#property NSMutableArray *menuArray;
In your viewDidLoad:
NSDictionary *option1 = [NSDictionary dictionaryWithObjectsAndKeys:#"image1.png",#"image",#"Option1",#"desc", nil];
NSDictionary *option2 = [NSDictionary dictionaryWithObjectsAndKeys:#"image2.png",#"image",#"Option2",#"desc", nil];
NSDictionary *option3 = [NSDictionary dictionaryWithObjectsAndKeys:#"image3.png",#"image",#"Option3",#"desc", nil];
NSDictionary *option4 = [NSDictionary dictionaryWithObjectsAndKeys:#"image4.png",#"image",#"Option4",#"desc", nil];
NSDictionary *option5 = [NSDictionary dictionaryWithObjectsAndKeys:#"image5.png",#"image",#"Option5",#"desc", nil];
//assign NSDictionaries to array
self.menuArray = [NSMutableArray arrayWithObjects:option1,option2,option3,option4,option5, nil];
And then you must have table view delegate methods like this:
#pragma mark Table View delegate methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [menuArray count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//return row height
return 32;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier =#"Cell";
//assign TableCell.h to access custom properties
TableCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
//get dictionary from menuArray
NSDictionary * dict = [self.menuArray objectAtIndex:indexPath.row];
UIImage *imageIcon = [UIImage imageNamed:[dict objectForKey:#"image"]];
//set image
[cell.img setImage:imageIcon];
//set the label text
cell.label.text = [dict objectForKey:#"desc"];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//research more about pushing another view controller.
//if chosen was option1
if (indexPath.row == 0)
{
NSLog(#"option1");
}
//if chosen was option2
if (indexPath.row == 1)
{
NSLog(#"option2");
}
//if chosen was option3
if (indexPath.row == 2)
{
NSLog(#"option3");
}
// if chosen was option4
if(indexPath.row == 3)
{
NSLog(#"option4");
}
// if chosen is option5
if(indexPath.row == 4)
{
NSLog(#"option5");
}
}
In pushing to other view controller, try to research more because it's a lot more explanation. Try this link: https://github.com/ECSlidingViewController/ECSlidingViewController
But with this codes, you must be able to populate your table and when you select a cell there will be a log. Hope this helps :)
In my app, I have a tableView, which contains 5 sections, each section contains only one row, I have inserted a customView on each row, The view consists of name and mobile number, when a section is selected, the name and mob. no. should of the "corresponding section" be passed to the next view.
I have inserted the screen shot below.
It seems you want to identify the section of the row for which didSelectRowAtIndexPath is invoked. You can get the section information in an NSIndexPath object itself by accessing 'section' property
Here is the class reference : https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int section = indexPath.section;
//...
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//get the name and phoneNo from currently selected cell.
NSString *name = cell.yourCustomView.nameLabel.text;
NSString *phoneNo = cell.yourCustomView.phoneNoLabel.text;
if(indexPath.section == 0)
{
//code for section 1 selected
YourNextViewController *nvc = [self.storyboard instantiateViewControllerWithIdentifier:#"YourNextViewControllerIdentifier"];
nvc.nameProperty = name;
nvc.phoneNoProperty = phoneNo;
[self.navigationController pushViewController:nvc animated:YES];
}
if(indexPath.section == 1)
{
//code for section 2 selected
}
if(indexPath.section == 2)
{
//code for section 3 selected
}
if(indexPath.section == 3)
{
//
}
if(indexPath.section == 4)
{
//
}
}
You can use this logic.
1) According to your views, each section have phone no & Name. So you can keep into one array which contains dictionary object.like below
[
{
name : "Chandru"
phoneNo: "90xxxxxxxx"
},
..........
]
2) So you can use this in cellForRowAtIndexpath: as, cell.nameLabel.text = [self.yourArray objectAtIndex:indexPath.section] objectForKey:#"name"];
3) So you can pass it to next view as nextVC.selectedPersonDetail = [self.yourArray objectAtIndex:indexPath.section] in didSelectRowAtIndexPath:
where selectedPersonDetail should be public property of NSDictionary. Otherwise you can use public method to hold as private variable.
On my UITableView I want to check how many times user has tapped the same row.
If user has tapped the same row three times I want to delete the row from the UITableView.
Can anyone please lead me to the solution? I tried doing:
for (NSIndexPath *indexPath in self.tableView.indexPathsForSelectedRows) {
count = count + 1;
NSLog(#"rowCount %d indexPath.row %#", count, indexPath);
}
But this doesn't increment the count number of times the row was tapped by user.
Assuming you want to delete the row only if the user select three times a row the same cell.
Create another variable lastSelectedRow where you keep the last selected row. (create underneath the implementation line)
#implementation myViewController
{
NSInteger = lastSelectedRow;
}
Next, you should verify that the row is equal to the last one selected, increment and check if the row have to be deleted:
for (NSIndexPath *indexPath in self.tableView.indexPathsForSelectedRows) {
// If the last selected row is the same, increment the counter, else reset the counter to 1
if (indexPath.row == lastSelectedRow) count++;
else
{
lastSelectedRow = indexPath.row;
count = 1;
}
// Now we verify if the user selected the row 3 times and delete the row if so
if (count >= 3) [tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
NSLog(#"rowCount %d indexPath.row %#", count, indexPath);
}
Hope it helps.
Create an NSMutableDictionary property, where the key's are the indexPath's and the value is the current count of taps. e.g.
#property (nonatomic,strong) NSMutableDictionary *rowTaps;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (!self.rowTaps) {
self.rowTaps = [NSMutableDictionary dictionary];
}
[self.rowTaps setObject:[NSNumber numberWithInt:[(NSNumber *)[self.rowTaps objectForKey:indexPath]intValue]] forKey:indexPath];
if ([(NSNumber *)[self.rowTaps objectForKey:indexPath]intValue] == 3) {
// Perform Delete Action - Delete row, and update datasource
}
}
Perform your check on the dictionary each time the selection occurs on a cell, then perform the necessary action.
Create the following property in the interface:
#interface ViewController () <UITableViewDelegate,UITableViewDataSource>
#property (assign,nonatomic) int counter;
#end
In your implementation you can increment the counter as follows:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.counter++;
NSLog(#"the count is %i",self.counter);
}
Create a NSMutableDictionary and set the key as the cell index, then for the value set the count (1 at first). When the count reaches three then you can do what you need.
//fake cell index (from indexpath)
NSNumber * pretendCellIndex = [NSNumber numberWithInt:4];
//Dict to track ocurrences
NSMutableDictionary *index = [[NSMutableDictionary alloc]init];
//If the dict has the index, increment
if ([index objectForKey:pretendCellIndex]) {
//Get value for the index
int addOne = [[index objectForKey:pretendCellIndex] intValue];
addOne++;
//Add back to index
[index setObject:[NSNumber numberWithInt:addOne] forKey:pretendCellIndex];
//Your condition
if (addOne>=3) {
//do what you need
}
}else{
//Havent seen so add
[index setObject:[NSNumber numberWithInt:1] forKey:pretendCellIndex];
}
I have two tableViewControllers, my first tableView contains a list of items called folders, on click of which I will open the another tableView called ItemsInfolder and display if they are present or else it will empty.
So for this I know that ItemsInFolder View should be an array of arrays, with each array at index position (row position) , but I am confused, on how to do it , how to call array present at each index on click of each folder.
updated according to comments below
//FolderTableView
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ItemsTableViewController *selectedFolder = [[ItemsTableViewController alloc] initWithNibName:#"ItemsTableViewController" bundle:nil];
selectedFolder.selectedfolder = [indexPath row];
[self.navigationController pushViewController:selectedFolder animated:YES];
}
//ItemsTableView
-(void)xyz operation
{
[m_ItemArray addObject:item];
[appDelegate.2dArray addObject: m_ItemArray];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[appDelegate.2dArray objectAtIndex:m_selectedfolder]count];(selected folder index coming from, folderTable)
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *testArray = [appDelegate.2dArray objectAtIndex:[indexPath row]];
tableCell.items.text = [testArray objectAtIndex:[indexPath row]];
return tableCell;
}
So friends, please help me out.
Regards
Ranjit
Considered a arrayOfFolders global and initialized, full of arrays containing your files, following this hierarchy :
arrayOfFolders :
{
[0] //Folder 0 (NSArray)
{
file1
file2
file3
}
[1] //Folder 1 (NSArray)
{
file4
file5
}
}
When you'll click on your folder inside your tableView, get the child array like that :
-(void)didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//To retrieve your array within your array at the seleted index
NSArray * arrayOfItemsInFolder = [[NSArray alloc] initWithArray:[self.arrayOfFolders objectAtIndexPath:indexPath.row] copyItems:YES];
//Do your stuff
}
Does this seems right to you?