I have an NSMutableDictionary with a specific key and value. This dictionary is inside an NSMutableArray. I want to update the dictionary with a specific key which is at a certain index inside the array. I want to find the index of this dictionary object. Currently, my dictionary is at index 0 and my editingIndexPath is 1 which is of NSIndexPath type, so editingIndexPath.row doesn't help me.
My code is as follows:
//UpdatedDateAndTime is the NSMutableArray.
//selectedDay is a NSString object.
//dateKeySelected is also a string key.
[[updatedDateAndTime objectAtIndex:editingIndexPath.row] setObject:selectedDay forKey:dateKeySelected];
My problem is that I want to get the right index of the dictionary that is found.
The answer used to be a for loop with a counter, but you're in luck: NSArray has a new method, indexOfObject:, which should do the trick just fine:
NSUInteger i = [myArray indexOfObject:#{myKey:myValue}];
Swift: index(of:)
If your array contains just one special NSMutableDictionary then use below code. I didn't test it but the idea is to search NSMutableDictionary class in the array. And you have to do this search in indexPath which equals to the cell that you want to assign some data.
#interface ViewController (){
NSMutableArray *array;
NSMutableDictionary *dictionary;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (indexPath.row == 1) {
for (int i = 0; i < array.count; i++) {
if ([updatedDateAndTime[i] objectForKey:#"open_house_updated_date"] == selectedDay) {
NSLog(#"%i th index contains NSMutableDictionary that you want",i);
//do whatever needed
break;
}
}
}
else{
//define other cells which doesn't contain NSMutableDictionary
}
return cell;
}
#end
I hope this is what you are looking for.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Unfortunatly I dont currently have internet on my laptop so I will have to describe my code, I have a mutable array of alphabetically sorted song titles. I have a uitableview that is currently displaying these however I want to have section heads and an alphabet index at the side of the table so I need to put these songs into an nsdictionary to display it, however I cant work out an an efficent method of sorting the array into the alphabetical sections (also has a # section, ive made a nsarray of section heads) in the nsdictionary.
There are many possibilities to prepare your data. But since your songs are already sorted your view controller could look something like this:
#interface TableViewController ()
#property (strong, nonatomic) NSArray *sectionTitles;
#property (strong, nonatomic) NSArray *songsInSections;
#end
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *songs = #[#"A song", #"Another song", #"Some other song", #"Yet another song"];
// store all the needed section titles
NSMutableArray *sectionTitles = [NSMutableArray array];
// store the songs in sections (arrays in array)
NSMutableArray *songsInSections = [NSMutableArray array];
// prepare the data for the table view
for (NSString *song in songs) {
// get the song's section title (first letter localized and uppercased)
NSString *sectionTitle = [[song substringToIndex:1] localizedUppercaseString];
// check if a section for the song's section title has already been created and create one if needed
if (sectionTitles.count == 0 || ![sectionTitle isEqualToString:sectionTitles[sectionTitles.count - 1]]) {
// add the section title to the section titles array
[sectionTitles addObject:sectionTitle];
// create an (inner) array for the new section
[songsInSections addObject:[NSMutableArray array]];
}
// add the song to the last (inner) array
[songsInSections[songsInSections.count - 1] addObject:song];
}
// "store" the created data to use it as the table view's data source
self.sectionTitles = sectionTitles;
self.songsInSections = songsInSections;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.songsInSections count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return self.sectionTitles[section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.songsInSections[section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.songsInSections[indexPath.section][indexPath.row];
return cell;
}
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return self.sectionTitles;
}
#end
Once a user finished entering text in a UITextfield I wand the data to be in a dictionary first and then the dictionary added to array. But for some reason after inserting into array .. It logs null..
.h
#interface Bread_TableViewController : UITableViewController <UITextFieldDelegate>
{
NSMutableArray * inventoryarray;
}
**.m**
- (void)textFieldDidEndEditing:(UITextField *)textField
{
// Make sure to set the label to have a ta
NSString*textfieldclicked;
if (textField.tag == 1) {
textfieldclicked=#"Unit";
} else if (textField.tag ==2) {
textfieldclicked=#"Case";
}
id textFieldSuper = textField;
while (![textFieldSuper isKindOfClass:[UITableViewCell class]]) {
textFieldSuper = [textFieldSuper superview];
}
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)textFieldSuper];
InventoryTableViewCell *cell = (InventoryTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
NSMutableDictionary * productinfo = [[NSMutableDictionary alloc] init];
[productinfo setObject:cell.product.text forKey:#"product"];
[productinfo setObject:textField.text forKey:textfieldclicked];
NSLog(#"productin %#", productinfo);
[inventoryarray addObject: productinfo];
}
-(IBAction)save{
NSLog(#"array %#", inventoryarray);
}
The non-visible cells do not actually exist. Only the visible ones plus one outside the screen at each end are actually in memory. The other ones are created when you scroll and their data is pulled from the data source.
As soon as a cell is pushed out of the screen (+1 cell) it will be removed from the hierarchy and added to the reuse pool.
TL;DR: You can't loop through out-of-screen cells since they don't exist. If you want to access the data for each item, do it in your data source.
alloc-init the array in which you want to add your objects.
do alloc-init of your dictionary outside the textFieldDidEndEditing method and where it scope it visible might be in viewDidLoad
like
#interface yourViewController ()
#property (strong, nonatomic) NSMutableDictionary * product info;
- (void)viewDidLoad {
self.productinfo = [[NSMutableDictionary alloc] init];
}
I have UITableView and NSDictionary. It populated like follow:
currentAlbumData = [album tr_tableRepresentation];
Where albums is simple NSObject class:
// h.file
#interface Album : NSObject
#property (nonatomic, copy, readonly) NSString *title, *artist, *genre, *coverUrl, *year;
-(id)initWithTitle:(NSString*)title artist:(NSString*)artist coverUrl:(NSString*)coverUrl year:(NSString*)year;
//m.file
-(id)initWithTitle:(NSString *)title artist:(NSString *)artist coverUrl:(NSString *)coverUrl year:(NSString *)year{
self = [super init];
if (self){
_title = title;
_artist = artist;
_coverUrl = coverUrl;
_year = year;
_genre = #"Pop";
}
return self;
};
And tr_tableRepresentation is category of Album class, returning NSDictionary:
//h.file
#interface Album (TableRepresentation)
- (NSDictionary*)tr_tableRepresentation;
#implementation Album (TableRepresentation)
//.m file
- (NSDictionary*)tr_tableRepresentation
{
return #{#"titles":#[#"Artist", #"Album", #"Genre", #"Year"],
#"values":#[self.artist, self.title, self.genre, self.year]};
}
That is the code i take from tutorial, so, in following lines we populate tableView data with NSDictionary values:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
//... Cell initialization code
cell.textLabel.text = currentAlbumData[#"titles"][indexPath.row];
cell.detailTextLabel.text = currentAlbumData[#"values"][indexPath.row];
}
Now I'm stuck. because I'm getting confused when i see syntax like that.
cell.textLabel.text = currentAlbumData[#"titles"][indexPath.row];
cell.detailTextLabel.text = currentAlbumData[#"values"][indexPath.row];
What exactly is going on here? What this lines of code do? I can understand that we accessing #"titles" and #"values" somehow, could you please rewrite that lines in more readable manner, without square brackets?
And how could we even get #"titles" and #"values" using just indexPath (integer number)? That may sound kind of silly, but I'm not get it. I thought we have to put string as a parameter to access NSDictionary values, not an integer.
It is just a short way of writing code:
currentAlbumData[#"titles"][indexPath.row] is same asĀ [[currentAlbumData objectForKey:#"titles"] objectAtIndex:indexPath.row]. Here, currentAlbumData is a dictionary. You get it's object for key titles, which is (supposedly) an array. Then you get the object at index indexPath.row of this array.
titles is the key for an NSArray of NSStrings. So is values.
currentAlbumData[#"titles"] asks the dictionary for the value at the titles keypath. This returns an NSArray that is indexed by NSUIntegers, such as indexPath.row.
Titles is an array so to get value at particular index you can use
cell.textlabel.text = [[currentAlbumData valueForKey:#"titles"] objectAtIndex:indexPath.row];
If you find this confusing then better store Titles inside an array and then use it below
NSArray *titles = [currentAlbumData valueForKey:#"titles"];
cell.textlabel.text = [titles objectAtIndex:indexPath.row];
My app is currently generating random numbers (see code below). What I want is to save that number once the user hits the "Save" button and show it on a table view.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.clickyButton setTitle:#"Generate" forState:UIControlStateNormal];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)handleButtonClick:(id)sender {
// Generates numbers 1 to 49, without creating duplicate numbers.
NSMutableSet * numberSet = [NSMutableSet setWithCapacity:5];
while ([numberSet count] < 7 ) {
NSNumber * randomNumber = [NSNumber numberWithInt:(arc4random() % 49 + 1)];
[numberSet addObject:randomNumber];
}
NSArray * numbers = [numberSet allObjects];
self.n1.text = [NSString stringWithFormat:#"%#", [numbers objectAtIndex:0]];
self.n2.text = [NSString stringWithFormat:#"%#", [numbers objectAtIndex:2]];
self.n3.text = [NSString stringWithFormat:#"%#", [numbers objectAtIndex:3]];
self.n4.text = [NSString stringWithFormat:#"%#", [numbers objectAtIndex:4]];
self.n5.text = [NSString stringWithFormat:#"%#", [numbers objectAtIndex:5]];
self.n6.text = [NSString stringWithFormat:#"%#", [numbers objectAtIndex:6]];
}
#end
Please explain me how I can save it on a table view. xcode beginner.
You should create a variable that's accessible within the scope of the whole class rather than just the specific -handleButtonClick: method, and then add the generated numbers to that variable - an array, set, etc...
From there, you can implement the table view to read the values from the variable via var[indexPath.row] (assuming it's an array), and display it. You will need to call [tableView reloadData]; once the array has been filled with objects to make sure that the tableview displays the data.
create a NSMutableArray for UITableViewDataSource and cache the number.
when a number created by the user,add this number into NSMutableArray.
reload UITableView and show all numbers.
If you use only one number you should think about displaying it in another UI element, preferably a UILabel I would say.
If you want to use a UITableView you will either have to create it with static cells (e.g. in a Storyboard) or configure the data source and delegate object for it (which doesn't really seem what you want right now, unless maybe if you wanted to display multiple random numbers in a list...)
Before anything you should make the array numbers as a variable. In that way it is much easier than creating n1,n2,n3,.... I will show you how to solve your problem based on an existing numbers NSArray variable defined.
You need to implement the UITableView delegates in your header file. So let's suppose this is your header file after implementing the delegates:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
Then take your tableview (IBOutlet or programatically) and set the dataSource and delegate in the implementation file. You should do this in the viewDidLoad: method like this:
[_tableView setDelegate:self];
[_tableView setDataSource:self];
After you have done this you need to implement the delegate methods for the UITableView. This ones:
This method will tell the Table View how many rows it needs to show. In your case is the size of the NSArray called numbers:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return numbers.count;
}
This method will tell the Table View what to show on each cell (DON'T FORGET TO ASSING THE CELL IDENTIFIER OF THE CELL IN THE INTERFACE BUILDER TO "Cell")
- (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];
}
cell.textLabel.text = [numbers objectAtIndex:indexPath.row];
return cell;
}
Use this method if you want to do something when the user touches a cell in the table view:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
Finally to add numbers to the list as the user touches the button you just need to add these lines of code to your method triggered by the button:
- (IBAction)handleButtonClick:(id)sender {
// Generates numbers 1 to 49, without creating duplicate numbers.
NSMutableSet * numberSet = [NSMutableSet setWithCapacity:5];
while ([numberSet count] < 7 ) {
NSNumber * randomNumber = [NSNumber numberWithInt:(arc4random() % 49 + 1)];
[numberSet addObject:randomNumber];
}
//In case you want to delete previous numbers
[numbers removeAllObjects];
numbers = [numberSet allObjects];
[_tableView reloadData];
}
My program has a tableview, I want to show selected items from the tableview in a textview
I have following code which shows only the last item of the NSMutablearray in textview:
I guess problem is the for loop but couldnt figure it out.
stands is NSMutablearray, selectItems is NSMutablearray, selected items is UItexview.
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
[selectItems addObject:[stands objectAtIndex:indexPath.row]];
for (NSString *yourVar in selectItems) {
selectedItems.text=yourVar;
NSLog (#"Your Array elements are = %#", yourVar);
}
[self.mytableView reloadData];
}
I try the following but it crashes:
[selectItems addObject:[stands objectAtIndex:indexPath.row]];
int length = [selectItems count];
for(int i=0;i<=length;i++){
selectedItems.text= [selectItems objectAtIndex:i];
}
how can I show all the items of NSmutablearray in a texview ?
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
[selectItems addObject:[stands objectAtIndex:indexPath.row]];
NSMutableString *exString = [[NSMutableString alloc]init];
for (NSString *yourVar in selectItems) {
NSLog (#"Your Array elements are = %#", yourVar);
[exString appendFormat:#"\n%#",yourVar];
}
selectedItems.text=exString;
[self.mytableView reloadData];
}
What about something like this? It takes each object, puts a newline in it, then adds it to exString to form one long chain of the objects in your array.
Make sure you properly allocated and inited selectItems. Just adding objects does not create the NSMutableArray. Then you also need to concatenate your elements instead of overwriting the UITextView over and over again.