Select multiple items from a tableview - Beginner - iphone

I need to add a TableView and i should be able to click several Items in that tableview and save it to a NSMutable dictionary or something suitable.
I know that you have to use a NSMutable Dictionary for this. But i don't understand how to do this.
Can someone please point a good tutorial or provide some sample codes for me.

You will have to use a delegate method for that.
First make sure your table view is set up well (delegate and datasource) and then
implement delegate 's :
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath.
You access the selected row index with : [indexPath row].
And then you can store this value.

THere was a post by Matt Gallagher at Cocoa With Love about this that you might find illuminating.
A bit dated, but the principles will be the same.

It really depends on your data model.
First of all you need a NSMutableArray not a NSMutableDictionary;
//declare an NSMutableArray in the interface
#interface Class : SuperClass {
NSMutableArray *_arrayWithMySelectedItems;
}
//in one of your init/preparation methods alloc and initialize your mutable array;
- (void)viewDidLoad {
[super viewDidLoad];
_arrayWithMySelectedItems = [NSMutableArray alloc] init];
}
//now before you forget it add release in your dealloc method
- (void)dealloc {
[_arrayWithMySelectedItems release];
[super dealloc];
}
//add this following code to your didSelect Method part of tableView's delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//if you have only one category, you will probably have something like this
[_arrayWithMySelectItems addObject:[dataModelArray objectAtIndex:indexPath.row];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

You can use NSMutableDictionary in this method as:
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableDictionary *dict = [NSMutableDictionary alloc] init];
[dict setObject:[NSString stringWithFormat:"%#", cell.Label.text] forKey:[NSString stringWithFormat:"Key%d", indexPath.row]];
}

declare a string inside didselect row of tableview then give that string = [your populated array objectAtIndex:indexpath.row]; then add that into dictionary or nsmutable array according to your wish.

Related

How to get a UITableViewCell's subtitle show how many times that specific cell was tapped?

I have a uitableview that displays the values of an array. I would like to know if there is a way to update the subtitle of its table cells, based on how many times each cell was tapped.
Thank you!
First of all, you'll want to use a NSMutableArray so you can change its contents after instantiation. Here's a basic over view of what I just tried to achieve your intended results:
In your interface
#property (strong, nonatomic) NSMutableArray *tapCountArray;
In your implementation
- (void)viewDidLoad
{
[super viewDidLoad];
self.tapCountArray = [NSMutableArray new];
int numberOfRows = 20;
for (int i = 0; i < numberOfRows; i ++) {
[self.tapCountArray addObject:#(0)];
}
}
Then the important part!
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tapCountArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString *text = [self.tapCountArray[indexPath.row] stringValue];
[cell.textLabel setText:text];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tapCountArray replaceObjectAtIndex:indexPath.row withObject:#([self.tapCountArray[indexPath.row] intValue] + 1)];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
When each cell is tapped the number in its detailTextLabel will be incremented up by one.
You shouldn't create a new array or set, that could lead to problems if the two arrays get out of sync with each other. The way to do it, as you suggested in your comment, is to use dictionaries. The way you said you were doing that is probably not the way, however. You want an array of dictionaries where the values for one key would be whatever your main data is and the value for the other key would be the number of taps. For example, lets call the two keys main and sub, and your main data is a set of names. The array of dictionaries would look like this: ({main:#"Tom",sub:1}, {main:#"Dick", sub:0}, {main:#"Harry",sub:2}, .....). In the tableView:cellForRowAtIndexPath:indexPath method you would provide the data to the cells like this:
cell.textLabel.text = [[array objectAtIndex:indexPath.row] valueForKey:#"main"];
cell.detailTextLabel.text = [[array objectAtIndex:indexPath.row] valueForKey:#"sub"];
I think you can just set up another array of the same length as the one you have now. Then when your didSelectRowAtIndexPath is triggered, increment your indexPath.row entry of the new array and refresh that cell. If you don't expect to shuffle the table, you don't need a dictionary.
You can insert the object into an NSCountedSet, and on your cellForRowAtIndexPath method, you would take the model object for the cell and verify the number of times it has been inserted into the NSCountedSet instance.
Take a look at the NSCountedSet documentation: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSCountedSet_Class/Reference/Reference.html

Accessing String from NSIndex

I currently have a UITableView that is populated by a .plist full of exercises. What I want to be able to do is access individual exercises within the table by storing each exercise that is clicked on into an array, that will later be used to populate a seperate UITableView.
How exactly do I get access to these individual cells so that I can store them into this array. Here is what I have so far:
-(IBAction) saveWorkout {
NSMutableArray *workout = [NSMutableArray arrayWithCapacity:10];
[workout addObject: ] // I'm assuming this is where I add a cell to an array (or atleast the cell's string).
}
Any help?
Without delving too much into the actual code part of your question, calling -cellForRowAtIndexPath to retrieve a title is (can be) extremely expensive, especially if it is called multiple times. Use -didSelectRowAtIndexPath: to get the index of the title within your datasource array, then add that object to your list. Call -saveWorkout when you are finished/reach a certain limit.
A same might look like:
-(void)didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
//other code and such...
//get the index of the object in our original array and add the corresponding object to the new array.
[customWorkoutArray addObject:[workoutArray objectAtIndex:indexPath.row]];
}
To restate #CodaFi in code:
#property (strong, nonatomic) NSMutableArray *selectedElements;
#synthesize selectedElements=_selectedElements;
- (NSMutableArray *)selectedElements {
if (!_selectedElements) {
_selectedElements = [NSMutableArray array];
}
return _selectedElements;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
id element = [self.myModel objectAtIndex:indexPath.row];
// this is the key: this array will now be the basis for your subsequent table of selected items
[self.selectedElements addObject:element];
// do something to your model here that indicates it's been selected
// have your cellForRow... method interrogate this key and draw something special
[element setValue:[NSNumber numberWithInt:1] forKey:#"selected"];
// reload that row so it will look different
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-(void)didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
You can get the index here by indexPath.row
}

how to pass a selected array from a uitable to another uitable

Can anybody guide me how to do something like this:
I managed to do the 1st & the last screen, I need to put in another 1 in between them.
Is there any tutorial that i can learn from ?
thanks alot :)
Create a uinavigationcontroller with uitableview should help you achieve your goal here.
There are many tutorials for that. A quick google search landed me this. Basically you can use a single navigation controller and a single uitableviewcontroller class and create add the items to them. If you are unable to grasp the concepts from that tutorial add a comment here on where you are stuck. I will try to edit this post accordingly.
in screen1:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Screen2 *screen2 = [[Screen2 alloc]initWithNibName:.......];
screen2.itsArray = [[NSMutableArray alloc] init];
if(indexPath.row == 1)
{
screen2.itsArray = yourArrayForScreen2_FirstRow;
}
else if(indexPath.row == 2){
screen2.itsArray = yourArrayForScreen2_SecondRow;
}else{ ...... }
[self.viewController pushViewCOntroller .....];
}
in screen2:
NSMutableArray *itsArray; #property and #snynthesize
now use itsArray as you need it. in screen2, do the same as in screen1 for the screen3
What you need is basically an NSMutableArray with NSMutableArray
for eg.
obj1,obj2,obj3...nil is the dict. in your example
NSMutableArray *middleScreenElement1 = [NSMutableArray arrayWithObjects:obj1,obj2,obj3...,nil];
NSMutableArray *middleScreenElement2 = [NSMutableArray arrayWithObjects:obj1,obj2,obj3...,nil];
NSMutableArray *middleScreenElement3 = [NSMutableArray arrayWithObjects:obj1,obj2,obj3...,nil];
NSMutableArray *firstScreen = [NSMutableArray arrayWithObjects:middleScreenElement1,middleScreenElement2,middleScreenElement3];
In your 1st TableView,add the following method..
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSMutableArray *middleScreenArray = (NSMutableArray*)[firstScreen objectAtIndex:indexPath.row];
NextTableViewController *nTVC = [NextTableViewController alloc]initWithArray:middleScreenArray];
}
now you can use the array to populate your table view just like the middle screen.
**note you have to create an initWithArray:(NSMutableArray*)array method in your middleScreenViewController
Hope it helps.. :)

UITableView with NSMutableArray

I’m populating a UITableView based on the values of an NSMutableArray. This table view has search results. If the user clicks in one of the results, one will navigate to another screen. If the user clicks “back”, the search results are filled in again. At this point, while the table view is being repopulated, the old values still appear, just as I want. However, since I’m doing:
- (void)viewWillAppear:(BOOL)animated
{
NSMutableArray *m = [[NSMutableArray alloc] init];
self.searchResultsArray = m;
[m release];
}
The old cells information is no longer available. Thus, the app crashes if the user clicks in one of the old cells or scrolls the UITableView because I’m accessing the mutable array which was reinitialized above.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *cellArray = [searchResultsArray objectAtIndex:indexPath.row];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
appDelegate.selectedCell = [searchResultsArray objectAtIndex:indexPath.row];
}
Do you have any suggestions concerning how should I do this properly?
Thanks.
this is because you are re-initalizing the array each time the view comes back in focus, the array will then have 0 objects in, causing the issue when you select a row and reference an index in the array that simply was wiped when the viewWillAppear is called.
why not init ' self.searchResultsArray ' in viewDidLoad (remembering to undo this with release when the device receives memory warning)
let me know how you get on.
You should reset the array only when the view loads:
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *m = [[[NSMutableArray alloc] init] mutableCopy];
self.searchResultsArray = m;
[m release];
}
You should always call the reloadData: method when changing the data in the UITableViewDataSourceDelegate instance.
Let me know if this helps
Please try below code:
- (void)viewWillAppear:(BOOL)animated
{
// Your search result array with your old values
// Now add or appened new data to your old search results.
[self.searchResultsArray addObject:#"Your Value 1"];
[self.searchResultsArray addObject:#"Your Value 2"];
[self.searchResultsArray addObject:#"Your Value 3"];
[self.tableView reloadData];
// if you need to add new values from a array put this code in a loop.
}
It should helps you...
Thx
It seems to me that you are not initialising the NSArray in the right method (viewDidLoad:).
Using XLData you don't have to care about where you set up the storage, reload the UITableView or add items to the NSArray (searchResultsArray) since it keeps track of the data (NSArray) and updates the UITableView accordingly and on the fly.

Use dictionary with didSelectRowAtIndexPath

I am trying to get the trail name from the selected cell and pass it on to the next view in didSelectRowAtIndexPath. How would I go about this?
http://pastebin.com/bgXNfjie
if I understood you correctly, then this is not such a big thing. You just have to make a property in TrailViewController to hold your value and assign it like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
TrailViewController *trailViewController = [[TrailViewController alloc] initWithNibName:#"TrailViewController" bundle:[NSBundle mainBundle]];
NSDictionary *dict = [rows objectAtIndex: indexPath.row];
trailViewController.trailName = [dict objectForKey:#"name"];
[self.navigationController pushViewController:trailViewController animated:YES];
[trailViewController release];
}
Instead of just the name, you'll probably want to assign the complete NSDictionary to a property of the TrailViewController,but thats up to you. I hope I could help...