Adding cell.textLabel.text value to an array and displaying it - iphone

i have a UItableView and i have two buttons on each cell. You can add or subtract 1 from the cell's textLabel. I add the cells current value +1 with this:
- (IBAction)addLabelText:(id)sender{
num = [NSString stringWithFormat:#"%d",[cell.textLabel.text intValue] +1];//<--- num is an NSNumber
number = [[NSMutableArray alloc]initWithObjects:num, nil];//<---- number is an NSMutableArray
[myTableView reloadData];
}
and I am trying to subtract the text and store it in an array with this:
- (IBAction)subtractLabelText:(id)sender
{
if ( [[cell.textLabel text] intValue] == 0){
num = [NSString stringWithFormat:#"%d",[num intValue] +0];
[number addObject:num];
[myTableView reloadData];
}
else{
num = [NSString stringWithFormat:#"%d",[num intValue] -1];
[number addObject:num];
[myTableView reloadData];
}
}
and im trying to set the cell.textLabel.text in the cellForRow like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *identifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
}
cell.textLabel.text = [number objectAtIndex:indexPath.row];//<---IM USING THIS LINE TO SET THE NEW TEXTLABEL
cell.textLabel.text = #"1";
return cell;
}
MY PROBLEM
So, the addition works, but the subtraction does not. It doesnt work at all when i press the button on the cell. Thanks in advance!!

At the risk of pointing out the obvious... you seem to have hard-coded the text property to #"1".
cell.textLabel.text = [number objectAtIndex:indexPath.row];//<---IM USING THIS LINE TO SET THE NEW TEXTLABEL
cell.textLabel.text = #"1";
The first line is probably doing what you think... but then you're immediately changing it back to #"1".
EDIT - Based on clarification in comments, here's what I think you want to do. I will modify your own code as posted.
Note that I put my addition into viewDidLoad as an example. You could do this in init, or any number of other places, at whatever point you know how many cells you want to show.
- (void)viewDidLoad {
self.number = [[[NSMutableArray alloc] init] autorelease];
for (int i = 0; i < [HOW MANY CELLS DO YOU WANT?]; i++) {
[self.number addObject:#"1"];
}
[myTableView reloadData];
}
- (IBAction)addLabelText:(id)sender {
// Note that I'm assuming here that your button is a direct child of the cell.
// If not, you'll need to change this.
UITableViewCell *cell = [sender superview];
NSInteger newNumber = [cell.textLabel.text intValue] + 1;
NSString *newNumberString = [NSString stringWithFormat:#"%d", newNumber];
[self.number replaceObjectAtIndex:cell.tag withObject:newNumberString];
[myTableView reloadData];
}
- (IBAction)subtractLabelText:(id)sender {
// Note that I'm assuming here that your button is a direct child of the cell.
// If not, you'll need to change this.
UITableViewCell *cell = [sender superview];
NSInteger newNumber = [cell.textLabel.text intValue] - 1;
newNumber = (newNumber < 0) ? 0 : newNumber;
NSString *newNumberString = [NSString stringWithFormat:#"%d", newNumber];
[self.number replaceObjectAtIndex:cell.tag withObject:newNumberString];
[myTableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
}
cell.tag = indexPath.row; // Important for identifying the cell easily later
cell.textLabel.text = [self.number objectAtIndex:indexPath.row];
return cell;
}
I don't want to get too much more in depth, but I would recommend you take a look at reloading only the cell modified, instead of calling [myTableView reloadData] every time.

Related

Xcode table view from array splitted

I'm trying to get a tableview starting from a string in this format "name1,link1,name2,link2..."
So what i'm actually doing is this:
-Get the string and put links and names into an array, then split the array into two lesser ones by the position of the objects
- (void)viewDidLoad
{
NSString *dataString = #"a,www.google.it,b,www.apple.it,c,www.youtube.it";
dataArray = [dataString componentsSeparatedByString:#","];
for (int i=0; i<[dataArray count]; i++) {
if (i%2==0) {
[dataArrayName addObject:[dataArray objectAtIndex:i]];
}
else {
[dataArrayLink addObject:[dataArray objectAtIndex:i]];
}
}
[super viewDidLoad];
}
-Set up the table view
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return [dataArrayName count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"myCell";
// Try to retrieve from the table view a now-unused cell with the given identifier.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
// If no cell is available, create a new one using the given identifier.
if (cell == nil) {
// Use the default cell style.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myCell"];
}
// Set up the cell.
NSString *cellName = [dataArrayName objectAtIndex:indexPath.row];
cell.textLabel.text = cellName;
return cell;
}
But when i run the application the view with the tableview is clear (there are empty rows)
What's the problem?
Have you initialized dataArrayName and dataArrayLink (ie, at some point, before you started adding objects to it, did you say dataArrayName = [[NSMutableArray alloc] init] or an equivalent?

Modify multiple rows on uitableview on view load

I have a UITableView that should have 33 rows. Each row represents a specific time slot in a day. When the view that holds the table view loads, I need it to populate each row accordingly.
I have an array of reservation objects that gets passed to the view. Each reservation contains a slot number, a reservation name and the duration of the reservation in slots.
What is the best way to populate the table, I am currently iterating through the array of reservations in the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method.
This is not giving me the results or the behavior I am expecting. The performance is extremly poor as it keeps iterating through loops and cells that shouldn't be blue are blue after scrolling. What is the best way to approach this? I have included the code below.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 33;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSString *timeStamp = [NSString stringWithFormat:#"%.2f", (indexPath.row + 14.0 ) / 2.0];
timeStamp = [timeStamp stringByReplacingOccurrencesOfString:#".50" withString:#":30"];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%#: ", timeStamp];
for (Reservation *temp in bookingsArray) {
if ((temp.slotNumber - 1) == indexPath.row) {
cell.textLabel.text = [NSString stringWithFormat:#"%#: %#", timeStamp, temp.reservationName];
cell.contentView.backgroundColor = [UIColor blueColor];
}
for (NSNumber *tempNo in temp.slotIdentifiers) {
if ([tempNo intValue] -1 == indexPath.row) {
//cell.textLabel.text = [NSString stringWithFormat:#"%#: Booked", timeStamp];
cell.contentView.backgroundColor = [UIColor blueColor];
}
}
}
return cell;
}
UPDATE
Trying the following gives me strange behaviour where all the cells turn blue after I start scrolling.
- (void)viewDidLoad
{
[super viewDidLoad];
bookManager = appDelegate.bookingManager;
bookingsArray = [[NSArray alloc] initWithArray:[bookManager getBookingsForCourt:1 onDate:[NSDate date]]];
namesArray = [[NSMutableDictionary alloc] init];
slotIndexSet = [NSMutableIndexSet indexSet];
for (int c = 0; c < 33; c++) {
[namesArray setObject:#"Available" forKey:[NSNumber numberWithInt:c]];
}
for (Reservation *temp in bookingsArray) {
[namesArray setObject:temp.reservationName forKey:[NSNumber numberWithInt:temp.slotNumber]];
for (NSNumber *slotNo in temp.slotIdentifiers) {
[slotIndexSet addIndex:[slotNo intValue] + 1];
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSString *timeStamp = [NSString stringWithFormat:#"%.2f", (indexPath.row + 14.0 ) / 2.0];
timeStamp = [timeStamp stringByReplacingOccurrencesOfString:#".50" withString:#":30"];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%#: ", timeStamp];
cell.textLabel.text = [namesArray objectForKey:[NSNumber numberWithInt:indexPath.row]];
if ([slotIndexSet containsIndex:indexPath.row]) {
cell.contentView.backgroundColor = [UIColor blueColor];
}
return cell;
}
You need to do two things to speed this up:
Convert bookingsArray to a bookingBySlotNumber array in such a way that the object at index i has slotNumber - 1 equal to i. You can do it by iterating over the original bookings array when you receive it.
Create a NSIndexSet called isBookedBySlotNumber containing indexes of items that have been booked. You can prepare it by going through all Reservation.slotIdentifiers, and marking the indexes of isBookedBySlotNumber for items that have been booked.
With these two pre-processed items in place, you can eliminate the nested loops altogether: the outer one will be replaced by a lookup in bookingBySlotNumber, and the inner one - by a loopup in isBookedBySlotNumber.

iPhone - Trying to Display 2 different object types in a table-view

I have a UITableView that I'm using to try and display 2 different objects - receipts and milages.
This is the original code I was using to try and accomplish this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Project *project = [[Project alloc] init];
project = [appDelegate.projects objectAtIndex:indexPath.section];
if (indexPath.row >= [project.receipts count])
{
if (indexPath.row >= [project.milages count]){
return NULL;
}
else {
//Create a new journey cell and set its UI values
MilageCell *cell = (MilageCell *)[tableView
dequeueReusableCellWithIdentifier:#"MilageCell"];
Milage *milage = [project.milages objectAtIndex:indexPath.row];
cell.locationLabel.text = milage.location;
cell.dateLabel.text = [NSString stringWithFormat:#"%#", milage.date];
cell.totalLabel.text = [NSString stringWithFormat:#"£%#", milage.total];
return cell;
}
}
else
{
ReceiptCell *cell = (ReceiptCell *)[tableView
dequeueReusableCellWithIdentifier:#"ReceiptCell"];
Receipt *receipt = [project.receipts objectAtIndex:indexPath.row];
cell.dateLabel.text = receipt.receiptDate;
cell.descriptionLabel.text = receipt.descriptionNote;
cell.amountLabel.text = [NSString stringWithFormat:#"£%#", receipt.amount];
return cell;
}
}
I'm aware that if I have 1 object in each of the arrays (project.receipts and project.milages) then this code won't work at all. I also know you can't return NULL from this method. What I'm trying to do is somehow display all my receipt objects, then all my milage objects (so say section 0 in the table view had 3 receipts and 3 milages, it would firstly display the receipts, then the milages). However I have absolutely no idea how to do this, can someone explain how I might solve this problem? Is there some way I could construct a single array of all the milage and receipt objects and then somehow discern which what kind of object I have in this method in order to use the appropriate cell type?
Thanks a lot,
Jack
Try this, I've just removed an if condition and subtracted the [project.milages count] from the index.row for the Receipt cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Project *project = [[Project alloc] init];
project = [appDelegate.projects objectAtIndex:indexPath.section];
if (indexPath.row >= [project.milages count]){
ReceiptCell *cell = (ReceiptCell *)[tableView
dequeueReusableCellWithIdentifier:#"ReceiptCell"];
Receipt *receipt = [project.receipts objectAtIndex:indexPath.row-[project.milages count]];
cell.dateLabel.text = receipt.receiptDate;
cell.descriptionLabel.text = receipt.descriptionNote;
cell.amountLabel.text = [NSString stringWithFormat:#"£%#", receipt.amount];
return cell;
}
else {
//Create a new journey cell and set its UI values
MilageCell *cell = (MilageCell *)[tableView
dequeueReusableCellWithIdentifier:#"MilageCell"];
Milage *milage = [project.milages objectAtIndex:indexPath.row];
cell.locationLabel.text = milage.location;
cell.dateLabel.text = [NSString stringWithFormat:#"%#", milage.date];
cell.totalLabel.text = [NSString stringWithFormat:#"£%#", milage.total];
return cell;
}
}
You can also use an UITableView with two different sections.

indexPath.row-1 is 4294967295

I have an indexPath.row that is 1 and logs 1(when using NSLog). If I call indexPath.row-1 (should return 0) it returns 4294967295.
I'm trying to return an objectAtIndex:indexPath.row-1 but that's when I get 4294967295.
Any ideas?
- (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];
}
// Configure the cell...
Singleton *singleton = [Singleton sharedSingleton];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([[prefs objectForKey:#"isYes"]boolValue] == 1 && randomMarker != 100)
{
//sets cell image
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,98,100)];
imgView.image = [UIImage imageNamed:#"stackoverflow.png"];
cell.imageView.image = imgView.image;
//sets cell text
cell.textLabel.text = #"Text";
self.checkedInCount == 100;
}
else if ([[prefs objectForKey:#"isYes"]boolValue] == 1 && randomMarker == 100)
{
//gets cell and cleans up cell text
NSLog(#"%#", indexPath.row);
NSString *title = [[[singleton linkedList]objectAtIndex:(indexPath.row-1)]objectForKey:#"desc"];
When you attempt to give an unsigned int (NSUInteger) a negative value, it often returns a very large positive value instead.
You are calling
NSString *tempDesc = [[[singleton linkedList]objectAtIndex:indexPath.row-1]objectForKey:#"desc"];
when indexPath.row has value 0, so the translation is:
NSString *tempDesc = [[[singleton linkedList]objectAtIndex:-1]objectForKey:#"desc"];
Since objectAtIndex: takes an unsigned integer as its parameter, -1 is converted to a garbage value of 4294967295.
To avoid this problem, don't subtract 1 from 0 by checking first that indexPath.row is positive.
Here's another problem:
NSLog(#"%#", indexPath.row);
This should instead read:
NSLog(#"%u", indexPath.row);
NSLog(#"%#", indexPath.row);
You shold use %d for integer as indexPath.row will return an integer
Use
NSLog(#"%d", indexPath.row);

Reading plist into TableView

I started this project with a simple plist of a dictionary with two arrays of strings. I now want to add more information and want to use this plist structure:
Root - Dictionary - (2 items)
Standard - Array - (3 items)
Item 0 - Dictionary - (4 items)
Color - String - Red
Rvalue - String - 255
Gvalue - String - 0
Bvalue - String - 0
Sorry about typing in the plist but the site would not let me post an image
I know that the RGB values could be numbers instead of strings but I have a reason for them being strings.
This is the code I used to read the simple plist:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *colorSection = [colors objectForKey:key];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if(cell == nil){
cell=[[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier: SectionsTableIdentifier] autorelease];
}
cell.textLabel.text = [colorSection objectAtIndex:row];
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton]; //add disclosure button to rows
return cell;
}
My question is what is the specific code to retrieve the contents of the color dictionaries to get the Colors for the cell.textLabel.text and also read the RGB values to add a subtitle. I've been working on this for several days and have read references and lots of examples and unfortunately can't solve the problem. Your assistance will be greatly appreciated.
So providing you have your Standard - Array stored against a Array you've defined in your .h file then something like this would work. In this example the array is stored against self.coloursArray.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if(cell == nil){
cell=[[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier: SectionsTableIdentifier] autorelease];
}
NSString* ColourString = [[self.coloursArray objectAtIndex:indexPath.row] valueForKey:#"Colour"];
NSString* rValue = [[self.coloursArray objectAtIndex:indexPath.row] valueForKey:#"Rvalue"];
NSString* gValue = [[self.coloursArray objectAtIndex:indexPath.row] valueForKey:#"Gvalue"];
NSString* bValue = [[self.coloursArray objectAtIndex:indexPath.row] valueForKey:#"Bvalue"];
cell.textLabel.text = ColourString;
NSString* subCellString = [NSString stringWithFormat:#"%#:%#:%#", rValue, gValue, bValue];
}
Hopefully that'll give a a hand.
First, do not use -[UITableViewCell initWithFrame:reuseIdentifier:]. It has been deprecated and will give you a warning, plus it will make your subtitle harder to implement. This code is a modified version of yours which loads the information, sets the title to the Color property, and sets the subtitle to a string containing the Rvalue, Gvalue, and Bvalue properties.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *colorSection = [colors objectForKey:key];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if(cell == nil) {
cell=[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: SectionsTableIdentifier] autorelease];
}
NSDictionary *color = [colorSection objectAtIndex:row];
cell.textLabel.text = [color objectForKey:#"Color"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#, %#, %#",[color objectForKey:#"Rvalue"],[color objectForKey:#"Gvalue"],[color objectForKey:#"Bvalue"]];
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton]; //add disclosure button to rows
return cell;
}