What (self.nsmutablearray)[indexPath.row] means? - ios

I'm developing a contact list for studying purposes and this question came while studying.
Here's the problem: I'm configuring a cell for my TableView and one of my friends said that I should use (self.nsmutablearray)[indexPath.row], however I don't understand why I should use (self.nsmutablearray) before [indexPath.row]. I know it's a dumb question, but I just can't understand how exactly the programming paradigm works.
Here's the code (Contact is a NSObject and contactList is a NSMutablArray):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ContactCell" forIndexPath:indexPath];
Contact *contact = (self.contactList)[indexPath.row];
cell.textLabel.text = contato.name;
return cell;
}

It's index subscripting.
self.contactList represents an array of Contact objects. You need to fetch a contact at a certain row in the table so you can populate the cell with data. indexPath represents a section and row in a table, and indexPath.row represents just the row. Therefore, you can write self.contactList[indexPath.row] which retrieves the element at that index from the array.
Alternatively, you could write [self.contactList objectAtIndex:indexPath.row]

Related

How do I only show text in a certain cell?

I have a populated array which I can display in the tableview, but I want to hide 3 of the cells text (out of 7 cells). I know the below code is wrong, but in this case I only want to show the text in cell 0.
cell.animal.text[0] = animalarray[0]
cell.animal.hidden = true
Because you don't have codes, I can only use words to describe how it should be done.
You need to have an array of the unwanted text that you do not want to show.
Inside your cellForRowAtIndexPath, you need to have a for loop, to go through the animalarray, and within the for loop, have an if-else statement to check whether if(unwantedtext == animalarray), then cell!.textLabel.text = " "
You need to show me codes for me to help you.
I'm gonna try to help you in Objective C, hopefully I can make the logic so clear the language difference doesn't matter.
Generally you are telling the TableView what to print for each cell in the below delegate method in your ViewController.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
cell.textLable.text = animalArray[indexPath.row];
return cell;
}
This is where you will decided which index in the animalArray you do or do not want to print. If your requirement is a static the simplest is to hardcode the the blocking.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(!(indexPath.row == self.indexIDontWantToPrint)) {
cell.textLable.text = animalArray[indexPath.row];
}
return cell;
}
If the indexes you do not want to print is dynamic and submitted to you by say an array.
You need to replace if(!(indexPath.row == self.indexIDontWantToPrint)) with checking if indexPath.row is inside the array of indexes you are to ignore.
NSArray has a handy containsObject method you can use to check if the array contains the current index the tableView wants to print. Be careful of the type difference of indexPath.row is NSInteger while NSArray needs to carry NSNumber for simple numeric numbers.
Adding more efficient logic than jo3birdtalk
1) Instead of having a extra array, you can creat an Object which contains a string & Bool.Add these objects in animalarray
2) Get the object from array at indexpath & check
if(animal.isShow == YES),if Yes show the text else hide label Or set blank string whatever you required
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
Animal * animal = animalArray[indexPath.row];
if(animal.isShow == YES)
{
show the text
}else
{
hide label Or set blank string whatever you requered
}
return cell;
}

Display two array values in single tableview cell

I want to display webservies array values in tableview for each cell i need to display two values Ex:total ten values mean each cell display 2 values in each row. webservies total value nine means each display two values last cell display one value. how can i achieve this help me. new for development.
Follow this tutorial for custom cell and design it the way you want:
Crafting Custom UITableView Cells
This is the method where you can set the values for the custom cell labels from each array:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
return cell;
}
Create a custom class of UITableViewCell say CustomCell and add 2 labels to it both occupying half of the space or as per your design what you need. Now say that they are labelOne and labelTwo.
From your Controller class you got the array of objects that you need to display in lables. In UITableViewDataSource method use this code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return (dataArray.count+1)/2; //This will provide correct row count for odd data set, such as when count is 9
}
and use this code to populate cell label text
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"customCell"];
}
cell.lableOne.text = [dataArray objectAtIndex:indexPath.row*2];
if((indexPath.row*2)+1 < dataArray.count){
cell.lableTwo.text = [dataArray objectAtIndex:(indexPath.row*2)+1];
}
return cell;
}
In cellForRow: you should send the cell the values from the array at [yourArray objectAtIndex:(indexPath.row * 2)] and [yourArray objectAtIndex:(indexPath.row * 2 + 1)]. so row 6 will get the objects for indexes 12 and 13.
Also you should always check if the objects exists. something like - if (yourArray.count > (indexPath.row * 2)) and if (yourArray.count > (indexPath.row * 2 + 1)) than send to cell else don't. (than you will get one object in cell when you get odd number of values.
Using % fetch the number of rows for the table view. Then for the last cell if value is null then display blank... you can have a basic logic for that. Take 2 lbls in each cell and display on those lables which contains value in it.

Manage tableview Cells from already stored data

Hi I am trying to make table view that has 5 cell and each cell automatically fills from the data or data type I have stored. here is the an example of what I have in mind, Please let me know if my question wasn't clear enough
cheers.
Maybe I asked my question in a wrong way, I'll try to explain it more.
So the Application I am making works this way:
I have 5 different Drill type that each has different condition, and I need to make a different drill recording stats (UI) and tableView for each drill type,  
So in the first table view that call Drills I have a cell that should show drill type and date that user made also one Create drill button that takes the user  to create drill (UI ), that has some attributes in it for example name, date , and DrillType(only 5 option),  
After this I have to make 5 different table and scoringViewControl for each drill type specifically that they be able to insert their stats as many times as they want.
And here I have problem, I don’t know what is the best way to manage navigating my cells in to the correct [drilltype] tableview..
(if I didn’t have to have some condition in create drill I would just made 5 statics Cell and navigate them into different direction)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.drill.drillType isEqual: #"Grouping"] ){
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Drill *drill = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = drill.drillType;
cell.detailTextLabel.text = drill.drillDate;
return cell;
}
else if([self.drill.drillType isEqual: #"Normal"] ){
static NSString *CellIdentifier = #"Cell2";
UITableViewCell *cell2 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Drill *drill = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell2.textLabel.text = drill.drillType;
cell2.detailTextLabel.text = drill.drillDate;
return cell2;
}
return 0;
}
If you need want to have many cells you should use dynamic dispatch. Use dictionary to map type of cell to the key (if statement). Here is code
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *cellIds = #{#"Grouping" : #"GroupingCellId", #"Normal" : #"NormalCellId"};
Drill *drill = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString *CellIdentifier = cellIds[drill.drillType];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[self configureCell:cell withObject:drill];
return cell;
}
Also if you need to do some specific configuration for cells you could do it in 2 ways:
1 - Subclass a UITableViewCell and implement method that does cells configuration. different cells will implement this method in different ways. This technic is called "Polymorphism". Some explanation
[cell setDrill:drill]
2 - Make a dynamic dispatch (call a method) depending on what type is it. The same tech nick as for getting different cells for different type.
NSDictionary *configMethods = #{#"Grouping" : #"configGrouping", #"Normal" : #"configNormal"};
NSString *method = configMethods[drill.drillType];
[self performSelector:NSSelectorFromString(method) withObject:cell withObject:drill];

Update single section of multi-section UITableView

I have a UITableViewController created in storyboard. It has two sections. The first section's rows contain controls laid-out in storyboard. I want to update the rows in the second section using values in an array.
I'm fairly new to iOS development. I understand how to use a UITableViewDataSource to update a table based on the array, but not how to restrict the updates to a specific section. Can anyone outline how to do this?
EDIT This seemed like a simple problem, so I thought I code would just obscure the question. Maybe I was wrong. Heres what I have:
My numberOfRowsInSection function returns 1 in the section number is 0, because the first section (the one I designed in storyboard) has a single row, otherwise it returns the number of elements in the backing data array:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0)
return 1;
else
return [myData length];
}
My cellForRowAtIndexPath function creates a cell if the section number is 1. But I don't know what to do if the section number is zero. How do I avoid having to recreate the rows I laid-out in storyboard?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 1)
{
cell.textLabel.text = [myData objectAtindex:indexPath.row];
}
else
{
// What to do here?
}
}
Well If you only have few static controls in the first section why won't you put these controls in a table header view instead? Thus you'll only have one section to worry about :)
In your method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPathadd this
Create 2 differents UITableViewCells and reference them like this
if (indexPath.section == 1) {
NSString *CellIdentifier = #"DynamicCell";
VideoCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//You are drawing your second section so you can use your array as values
cell.property1...
cell.property2...
cell.property3...
return cell;
}else{//If you have only 2 sections then else represent your first section
//You are drawing your first section
NSString *CellIdentifier = #"StaticCell";
VideoCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
You can change the row value in the delegate method
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
To identify the section, just use:
indexPath.section
You can use reloadRowsAtIndexPaths: with an array of all the indexPaths that are in the wanted section, built with a loop and a NSMutableArray.
- (void)reloadSections:(NSIndexSet *)sections
withRowAnimation:(UITableViewRowAnimation)animation;
The parameter "section" is An index set identifying the sections to reload.

Import 495 Cell to TableView

I want to create a table-view with 495 cells.
I want to import cells with NSArray, is it right way?
If yes, how can create 495 cells with simple code?
Not like this :
#"Cell 1" # "cell 2" #"cell 3", #"cell 4", #"cell 5" ............. #"cell 495"
you will have to return the value of 495 in the '-tableView:numberOfRowsInSection:' method like
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Returning num rows");
return 495;
}
then populating the table with your array
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.text = [array objectAtIndex:row];
return cell;
}
here i assumed that you are storing text data in the cells.
Also create the array in viewDidLoad method.
The thing to remember with tables is that there is complete separation between the data and the actual cells displayed in the interface. The data list can be arbitrarily long but the tableview will only display as many actual cells as needed to fill up the physical screen. This is what -tableView:cellForRowAtIndexPath: is for. The table tracks which rows are actually visible to the user and then ask the datasource for data just for the displayed rows.
You can use an NSArray to hold your data and the easiest way to populate the array is to read it in from a file. You can create a plist file with the /Developer/Applications/Utilities/Property List Editor.app (part of the standard developers tools) that NSArray can read in directly with initWithContentsOfFile:. (If you just want to create a long list of data to experiment with, you can use NSMutableArray and populate it with a loop.)
In your case, you have 495 entries but the table will only display about 9 cells at a time (just simple default text cells). At the start it will display tables indexed 0-8. The table will call -tableView:cellForRowAtIndexPath: 9 times passing one index i.e. 0,1,2...7,8 each time. Your method will then find the the object in your array at that index e.g. [myArray objectAtIndex:index]. As the user scrolls, the index passed changes. When rows 300-308 are displayed the indexes passed are 300,301,...307,308.
No, this is not the correct way. See the documentation for UITableViewDataSource. Specifically, you'll want to implement -tableView:numberOfRowsInSection: and -tableView:cellForRowAtIndexPath:.

Resources