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
Related
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.
I've seen a number of people who have asked a similar thing, but answers to their questions are not the answers to mine.
1) I have created a single view application with an empty View Controller. In that, I dragged a new Table View (style Plain) with a single prototype cell of style Basic.
2) I am trying to learn about dynamically changing the behaviour of TableViews, so I have a mutable array called sectionRows, which will contain the number of rows per section. At the moment, a single section with a number of rows would be an achievement :)
3) In my ViewController.h I have set the delegates
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#end
I have also control-dragged from the TableView to the ViewController Yellow-Circle and set the datasource and delegate outlets.
4) In my ViewController.m, I have defined some global variables
#interface ViewController ()
{
NSMutableArray *sectionRows;
UITableView *myTableView;
}
The first is my data array (containing the number of rows per section and the second is a pointer to my TableView, which I have identified using a numeric View tag of '1'.
5) In my viewDidLoad, I initialize everything:
- (void)viewDidLoad
{
[super viewDidLoad];
myTableView = (UITableView *)[self.view viewWithTag:1];
sectionRows = [[NSMutableArray alloc] init]; // Create sectionarray
[sectionRows addObject:[NSNumber numberWithInteger:1]];
myTableView.dataSource = self;
myTableView.delegate = self;
[myTableView reloadData];
}
As you can see, I even make sure that I set the datasource and delegate again but this hasn't made any difference.
5) I have overloaded 3 methods.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Returning %# rows", [sectionRows objectAtIndex:section]);
return (NSInteger)[sectionRows objectAtIndex:section]; // the number referenced in the array...
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(#"Returning %li sections", sectionRows.count);
return sectionRows.count; // the size of the sectionRows array
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"xxx";
NSLog(#"Setting cell to %#", cell);
return cell;
}
Now, when I run this, I am getting NSLog returning confirmation that there is a single section and a single row:
2014-07-27 19:58:34.599 TableViewTests[12877:60b] Returning 1 sections
2014-07-27 19:58:34.600 TableViewTests[12877:60b] Returning 1 rows
However, as you can see cellForRowAtIndexPath is not being called.
None of the other things I have seen point to what I am doing wrong. I am doing what I thought I did successfully in another simple project (to learn) but I must be doing something else differently.
Any ideas what I am missing?
Thanks in advance
Jon
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Returning %# rows", [sectionRows objectAtIndex:section]);
return (NSInteger)[sectionRows objectAtIndex:section]; // the number referenced in the array...
}
This is incorrect. You cannot cast what you get from your array to an NSInteger. It's a pointer. Assuming you store NSNumbers into the array:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Returning %# rows", [sectionRows objectAtIndex:section]);
return [[sectionRows objectAtIndex:section] integerValue]; // the number referenced in the array...
}
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];
}
I got a table view with approx 45k items. I want to use the indexbar to be able to scroll faster through my list.
Now I've looked at other questions on here, but I just can't figure out what to do.
I've got the following two functions:
-(NSArray*)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return alphabetsArray;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return index;
}
I don't understand what I should do next. Like, I have an array called airports which is sorted alphabetically. What should I be doing with this array?
update
so I found an article I could use and I'm pretty close now, I think. My table view only shows 2 items now though.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"ROWS METHOD CALLED");
NSArray *unsortedKeys = [alphabetizedAirports allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:section];
NSArray *airportsForSection = [alphabetizedAirports objectForKey:key];
return [airportsForSection count];
}
I have about 60 items in my sortedKeys array. The airportsForSection array only gets 2 items though so when it returns the array, the tableview only shows 2 items. Any ideas how to solve?
I want to only show some of the items in an array, but can't figure out how to do it.
This is the code I have that currently shows all objects in the array:
#property (strong, nonatomic) NSArray *springs;
#property (strong, nonatomic) NSMutableArray *leafs;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Spring *spring = [springs objectAtIndex:indexPath.section]; // 13 objects
Leaf *leaf = [spring.leafs objectAtIndex:indexPath.row]; // 30 objects
cell.textLabel.text = league.shortName;
return cell;
}
So I would like to only show 5 of the 30 leaf objects from that array I created, and not show all of them. Is there any way to do that?
(I'm using an API to pull the items into the Array)
Thanks for the help, will post any specific code or other info needed!
EDIT
Added per request:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
Spring *spring = [springs objectAtIndex:section];
return spring.leafs.count;
}
I'm using RestKit for the object mapping.
Use [NSArray objectsAtIndexes:] (reference) to get a subset of the array.
Leaf *leaf = [spring.leafs objectAtIndex:indexPath.row];
// This will include objects 0-4:
NSRange range = NSMakeRange(0, 5);
NSArray *subset = [leaf objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:range]];
Just adjust range to whatever start/length you want in the subset.
EDIT: Of course any subset logic in this method will also have to be duplicated in the numberOfRowsInSection: delegate method, else your app with throw an exception.
How about in your tableView:numberOfRowsInSection, don't return a full count full spring.leafs? For instance,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
Are you trying to lazy load them, or do the rest of them just not matter? Good luck.