I'm having trouble deciding.
I created a model class, and another one as a singleton,
the singleton uses a NSMutableArray and returns a NSArray as a copy.
One of the UITableViewController will show the array of data.
The question is, if I want to show different data on each UITableViewController should i create multiple arrays and methods that save and edit the arrays or is there a better way to do this?
On your UITableViewDataSource methods, you can decide what information to return based on which TableView is calling the method. For example:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//Check which tableview is calling
if (tableview == self.tableView1) {
// Return the number of sections for each possible Table
return 1;
} else {
return 2;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
// If you're serving data from an array, return the length of the array:
if (tableview == self.tableView1) {
// Return the number of sections for each possible Table
return [dataArray1 count];
} else {
return [dataArray2 count];
}
}
And the same for any DataSource/Delegate methods you may need to implement.
Hope that helps!!
Related
I Have a one table view and i have two array. My arrays name AllItems and SpecialItems. I Use segment control. I wantto if segment value is 0 tableview load AllItems Array, When change segment value and value is = 1 than mytableview reload tada but SpecialItems array. Can u help me please. Thanks.
I solved this problem with table tag.
- (IBAction)segmentControlChanged:(UISegmentedControl *)sender {
if (sender.selectedSegmentIndex == 1) {
mytable.tag = 1;
}
else
{
mytable.tag = 0;
}
[mytable reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView.tag==1)
{
return [specialItems count];
}
else
return [allItems count];
}
You could create two data source classes that implement all the UITableViewDataSource methods: one for AllItems and one for SpecialItems. To switch between the two, connect a valueChanged action. In the method that is called, set the data source and reload the table view.
- (void)valueChange:(UISegmentedControl *)sender
{
if (/* condition for all items */) {
self.tableView.dataSource = self.allItemsDataSource;
} else {
self.tableView.dataSource = self.specialItemsDataSource;
}
[self.tableView reloadData];
}
I would personally create an array which the data is loaded from. Put this in your implementation:
NSArray * _tableData
Then in your viewDidLoad just allocate this for the array which we want it to start on.
_tableData = [[NSArray alloc] initWithArray:allItems];
This initially loads the data we will always see as the segment control starts on index 0. We have to set the initial data somewhere so the tableView loads with some data in it.
Then set the number of rows and the cellForRowAtIndex to pick up from the _tableData array
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _tableData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView_ cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [tableView_ dequeueReusableCellWithIdentifier:bCell];
// Here we use the specific array as we would normally
return cell;
}
This step means the tableView will load with the array. Even if the array is empty the view will still load as the number of cells will be zero.
Now in our value changed function we can reset the array as we need to:
- (IBAction)segmentControlChanged:(UISegmentedControl *)sender {
if (sender.selectedSegmentIndex == 1) {
_tableData = allItems;
}
else {
_tableData = specialItems;
}
[self.tableView reloadData];
}
You just need to make sure the segment control changed is linked up in the XIB file (or programatically) and that you reload the table after choosing the array.
This kind of thing is actually really easy to do. I would definitely recommend working it through step by step if you're having trouble. Make sure each step is working before applying the next:
Get the tableView loading with both sets of data individually
Confirm that the segment control is calling the change function when clicked
Then that should do it
I have two tables in the same class, I need each table contains different data but i have a trouble with the delegate... How can make each table contains a separate delegate? Thanks, sorry for my English.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1; }
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [dataTable1 count];
}
-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CeldaFamilia *cell = (CeldaFamilia *)[aTableView dequeueReusableCellWithIdentifier:#"CeldaFamilia"];
if (!cell) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CeldaFamilia" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.propTextFamilia.text =[dataTable1 objectAtIndex:indexPath.row];
return cell;
}
You can do this by looking at the tableView argument that was passed in. Example:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.tableView1) {
return [dataTable1 count];
} else /* tableView == self.tableView2 */ {
return [dataTable2 count];
}
}
With this pattern, you need to put if statements in all of your UITableViewDataSource and UITableViewDelegate methods.
Another way to do it is to make one method that returns the array of data for the table view:
- (NSArray *)dataTableForTableView:(UITableView *)tableView {
if (tableView == self.tableView1) {
return dataTable1;
} else /* tableView == self.tableView2 */ {
return dataTable2;
}
}
Then use that function in each of your data source/delegate methods. Example:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self dataTableForTableView:tableView] count];
}
Your tableView:cellForRowAtIndexPath: method might still need to have an if statement, depending on what the data looks like for each table.
However, I recommend you don't use either of those patterns. Your code will be better organized and easier to understand if you make a separate data source/delegate for each table view. You can use two instances of the same class, or you can make two different classes and use one instance of each class, depending on your needs.
If you set the tags of each tableView to different numbers, you can use that to differentiate them.
For example, you can do
tableView1.tag = 1;
tableView2.tag = 2;
Then in your delegate and dataSource methods, you can do:
if (tableView.tag == 1) {
//first table data
}
else if (tableView.tag == 2) {
//second table data
}
You can add other class for second table (secondTable) and implement in it data source and delegate table view protocols. And in your view controller, which contains 2 tables in viewDidLoad :
SecondTable *second=[SecondTable alloc] init];
second.delegate=self;
second.datasource=second;
And your second table would be a object of SecondTable class, and first table you do like always.
I have two tableviews and cells are configured depending on which table view it is, they are implemented in the cellForRowAtIndexPath method via indexpath.section. However, the two tableviews have a different number of sections. Is there a way to go about this issue? Thanks
When i said they had different section numbers i meant the following:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if(tableView==byTeam) {
return [teamnameswithoutRepeat count];
} else {
return [JSONPointsArray count];
}
// Return the number of sections.
}
When i use the following in cellforrowatindexpath:
label.text=[currentarray objectAtIndex: indexpath.section];
there is a range error because indexpath.section is too big, it is using the JSONPointsArray to determine the number of sections, however when i run the app the by team tableview has the correct amount of sections.
Your cellForRow... method needs to be similar:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == byTeam) {
// process the "byTeam" table using the teamnamesiwthoutRepeat array
} else {
// process the other table using the JSONPointsArray array
}
}
I have two UITableView which appears according to UISegmentControl.selectedSegmentIndex. The first table is grouped style and the second is plain.
NSFetchedResultsController is for the first UITableView, and NSMutableArray for the second.
In my numberOfSectionsInTableView:
return [_fetchedResultsController.sections count];
In this case the second UITableView's data displays for 3 times (because FirstTableView section count = 3).
I would like for the second tableView numberOfSectionsInTableView
return 1;
You should check which tableview you are displaying before returning the count. You can use the tableView input param for this.
For eg:-
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == self.firstTableView) //or (tableView == firstTableView)
return [_fetchedResultsController.sections count];
else
return 1;
}
You can use the following condition...
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
if(tableView == firstTableView)
return 1;
else if (tableView == secondTableView)
return 2;
//... and so on you can do like this....
}
All the best !!!
I guess you are setting the same data source for both table views. If that is the case, then in your:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
if(tableView == firstTableView){ //assuming you have a reference to the first table view
return [_fetchedResultsController.sections count];
}else{
return 1;
}
}
You will have to do this in all your datasource methods. Instead it would be easier to make the datasource of the tableviews different.
To do this you can drag an object (the blue cube ) from the object library and set its class as say, SecondTableDatasource. And then set this object as the datasource for your second table, and implement the corresponding datasource methods in that class.
You can add tag for each tableView and check for each tag in numberOfSectionsInTableView
I have UIview contains tableview with search display controller
after searching it display the same table my expectation I have a problem with :
TableView numberOfRowsInSection# so I debugged it. it display search view but it doesn't fire the if statement
- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == aSearchDisplayController.searchResultsTableView)
{
return [self.searchResults count];
}
else
{
return [collection count];
}
}
The first parameter in your delegate function is called theTableView and not tableView, so you should compare
if (theTableView == aSearchDisplayController.searchResultsTableView)
...