Objective-C UITableView index - objective-c

How do I read always the most upper line (cell.textLabel.text) in a UITableView?
I have two slightly different approaches;
1:
UITableViewCell *cell2 = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText2 = cell2.textLabel.text;
NSLog (#" cellText2 = %#", cellText2);
2:
NSMutableString *newidea = [self.array objectAtIndex:indexPath.row];
NSLog (#"newidea = %#", newidea);
Both codes are inside the method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
self.array is same array that fills up the tableView.
The former approach always shows text from the sixth cell. The latter approach always shows text from the fifth cell. In my tableview there is four cells at a time.#
What I want to get is the text from the most upper cell.

I think you have the wrong approach. You don't read values from cells, instead you let the cells read values from your data array. A cell can always have an arbitrary value since they are reused. Even if you have 30 "cells" in your table view there may only be 5 existing actual cells. When a cell goes outside the table view when you scroll, it is moved to the bottom and reused as the next cell. That's why you always have to set the values for each cell on the index path.
Instead you should get the value in the first cell from your data array if you have one. When the table view asks what title the cell att indexPath.row == 0 should have, you give it to it in cellForRowAtIndexPath, for example from an array called "_cellTitles" containing 30 strings for 30 different cells.
If you want to get the text from the "most upper" visible cell, then you can call indexPathsForVisibleRows on the table view. The first object in the returned array is the index path for the most upper visible cell. You can check the string in your array at index indexPath.row.
Example:
NSArray *visibleRows = [self.tableView indexPathsForVisibleRows];
NSIndexPath *firstVisibleCell = [visibleRows objectAtIndex:0];
NSString *firstVisibleCellTitle = [_myDataArray objectAtIndex:indexPath.row];

If you always want to read from first row, instead of indexPath just say 1 there. That way it will always read from the first row.

Related

Objective-C Update Array of objects

I have the following entry that updates a labels text with the value:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *row = [tableView dequeueReusableCellWithIdentifier:#"TICKET_ITEM"];
UILabel *itemDiscount = (UILabel *)[row viewWithTag:502];
itemDiscount.text = [[arrayOfItem objectAtIndex:indexPath.row]TICKET_ITEM_DISCOUNT];
return row;
}
My problem is that after the fact I have button that allows for setting the discount (which is initially 0). After adjusting a slider I want to be able to take that discount % and update itemDiscount.text with the new value. I figure the way I need to do this is to update the arrayOfItem TICKET_ITEM_DISCOUNT entry and then use reloadData. But how do I update just the single item in the array?
Check out Apple's documentation on NSArray.
There are a variety of methods that could solve your problem.
indexOfObject:
or
indexOfObjectPassingTest:
spring to mind.
To edit an NSArray you'll need to make a mutable copy of the array then assign it back again:
NSMutableArray *temp = [arrayOfItem mutableCopy];
//update your value here
arrayOfItem = temp;

Populate NSTableView with unknown number of columns

I have a NSTableview and a button. NSTableview has a unknown number of columns.
The first column has a image well and 2 text boxes, the others (again, unknown number) are normal textbox columns.
The button opens up a file open dialogue. Once I choose the files (.jpg) I would like to process them.
So far everything is made (chose files, columns, etc..) what is missing is the populating of the table:
I have the loop that goes through all the selected files. What is the best way to do this:
display the image in the image well of the first cell,
type the filename in the first textbox of the first cell,
type the filepath in the second cell of the textbox,
type "YES" in all other columns.
My difficulty is that I have no idea how many columns will be there since it depends from the user. The number of columns will not change during Runtime. they are set up at startup based on the configuration. if the configuration is changed then the app should be reloaded.
I am a beginner in Objective-C/Cocoa programming.
EDIT:
additional info as requested:
It is a view based NSTableView
each column represents an action that has to be taken in a later moment on an image. the program user can decide what and how many actions to take, thats the reason for a unknown amount of columns in the table view.
You can add columns programmatically using addTableColumn:. This method takes an NSTableColumn instance that you can create in your code.
The rest of your architecture (displaying images, etc.) does not particularly change from "normal" code just because the columns have been added dynamically.
Here is a snippet that should get you started:
NSTableColumn* tc = [[NSTableColumn alloc] init];
NSString *columnIdentifier = #"NewCol"; // Make a distinct one for each column
NSString *columnHeader = #"New Column"; // Or whatever you want to show the user
[[tc headerCell ] setStringValue: columnHeader];
tc.identifier = columnIdentifier;
// You may need this one, too, to get it to show.
self.dataTableview.headerView.needsDisplay = YES;
When populating the table, and assuming that the model is an array (in self.model) of NSDictionary objects, it could go something like this;
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSString *columnIdentifier = tableColumn.identifier;
NSDictionary *rowDict = [self.model objectAtIndex: row];
NSString *value = [rowDict valueForKey: columnIdentifier]; // Presuming the value is stored as a string
// Show the value in the view
}
More in the docs.
When user adds a column or row, you should reflect it in your model (by binding or by code), so you know the size of your table, when you need to populating it.
set tableView.delegate (in code or in Interface Builder), reference here
implement:
- (NSView*) tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row
{
Item* itemView = [tableView makeViewWithIdentifier:#"rowItem" owner:self];
/*Here you populate your cell view*/
id entryObject = [self.entries objectAtIndex:row];
[itemView setEntry:entryObject];
return itemView;
}
and then invoke [tableView reloadData];
maybe for you better to use this method
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
Just see the NSTableViewDataSource and NSTableViewDelegate

UITableView multiselect

I have a uitableview with 50 rows populated from a predefined nsarray.
How can I select multiple the rows with say maximum 3 allowed at a time and show check when selected and remove check when deselected/
I am really new to xcode and any help is much appreciated. Thank you.
Your data needs to keep track of whether it is selected or not.
Two common ways are: each object in your predefined array has a BOOL that indicates whether or not it is selected, or you keep a second array that holds only references to selected objects. Since you're limited to three selected, the second option might be better.
When someone selects a cell in your table, you change the selection status of the related object, either switching its BOOL or adding/removing it in the extra array. This is also the place to check whether you already have as many selections as you allow. If selections have changed, you then tell your table to reload data.
In cellForRowAtIndexPath: you check whether or not the object is selected and mark it accordingly.
int counter = 0; //keep track of how many rows are selected
int maxNum = 3; //Most cells allowed to be selected
//Called when the user selects a row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//If the cell isn't checked and there aren't the maximum allowed selected yet
if (cell.accessoryType != UITableViewCellAccessoryCheckmark && counter < maxNum)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
counter++;
}
else if (counter >= maxNum) return; //Don't do anything if the cell isn't checked and the maximum has been reached
else //If cell is checked and gets selected again, deselect it
{
cell.accessoryType = UITableViewCellAccessoryNone;
counter--;
}
}
You might also want to keep an array of indices of the cells that are selected, in case you want to do something with the data that's in them. If you don't know how to do this, let me know and I'll add the code.
Notes:
You need to be implementing the table view delegate protocol in order to have this method called correctly.
This isn't the "best" way to do it (using cell content to keep track of selection is generally frowned up) but it is very easy.
You might run into problems with cell reuse. If you want to fix that, store the cell's index and set the accessory type in cellForRowAtIndexPath

Objective-c Parse JSON Response

I have been doing a lot of reading but I have not been able to find anything close to what I am trying to do. I am getting a JSON response and populating a UITableView with the results. When the user selects the row on the UITableView I want to grab the corresponding "id" value that is associated with the name displayed. Example JSON response:
{"active":true,"created_at":"2012-05-12T03:04:21Z","description":"Test 1",
"id":11,"name":"This Is A Test","updated_at":"2012-05-12T03:04:21Z"}
So I set the UITableView row with a name of This Is A Test and when the user selects that I want to return the number 11 as being selected. In the didSelectRowAtIndexPath function I can pull the
UITableViewCell *selectedCell = [self.tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = selectedCell.textLabel.text;
sc.selectedCategory = cellText;
Which will give me the name of the object but how can I call the dictionary again and get the value of "id" where the name matches the selected cell? I am pretty new to objective-c but have been doing java for years. Any examples would be great.
Thanks in advance!
What you have there is a dictionary. You need to cast the Array objectAtIndex (tableview index path) as an NSDictionary object and then use valueForKey.
Something like the following in the didSelectRowAtIndexPath:
NSDictionary *selRow = (NSDictionary *)[myArray objectAtIndex:indexPath.row];
NSInteger myID = [[selRow valueForKey#"id"] intValue];

Displaying array in uitableview

I have an array created like this:
[currentQuizArrayQuestions insertObject:[quizArrayQuestions objectAtIndex:randomIndex] atIndex:0];
How do I access its data to display in the table?
I'm trying this:
NSString *cellValue = [currentQuizArrayQuestions objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
I know it's wrong, but how do I get to the data array object stored in the currentQuizArrayQuestions array.
You need to implement the cellForRowAtIndexPath method. See this tutorial on UITableViews: http://adeem.me/blog/2009/05/19/iphone-programming-tutorial-part-1-uitableview-using-nsarray/
That one uses a UITableViewController, but the idea is the same.
Edit:
To use a different array, do the same thing with the cell for row at index path method, changing the array that the cellValues come from according to what you need. Then call [tableView reload]; which will run through cellForRowAtIndexPath with the contents of the new array.