Two Tableviews in one Controller - ios

So I'm trying to make two tableviews in one view and I'm having some trouble.
I've read some other response on how to do it but they don't exactly help me.
In my .h file I made two outlets for two views calling them myFirstViewText and mySecondViewTex
So in my m files for - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
I want to be able to print out seperate values in each different controller and I'm not too sure since you only return 1 cell?
So far i've Done this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Rx";
static NSString *CellIdentifier2 = #"allergies";
UITableViewCell *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:CellIdentifier];
UITableViewCell *cell2 = [tableView dequeueReusableHeaderFooterViewWithIdentifier:CellIdentifier2];
if(!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (!cell2) {
cell2 = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
}
if (tableView == self.myFirstTextView ) {
cell.textLabel.text = #"HI JAZZY";//[RxDict objectAtIndex:indexPath.row];
}
if (tableView == self.mySecondTextView) {
cell.textLabel.text = #"BYE JAZZY";//[RxDict objectAtIndex:indexPath.row];
}
tableView = self.mySecondTextView;
cell2.textLabel.text = #"I love Jazzy :D";
return cell2;
This prints "I love Jazzy" in my first TableView and nothing gets printed in the second one. Why does this happen and how can I fix it?
Thanks :D

This method gets called by all tableViews that have an instance of your class set as their dataSource.
This means you need to check which tableView was asking for cell number so-and-so.
So, your method should basically look like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == rxTableView) {
//prepare and return the appropriate cell for *this* tableView
}
else if (tableView == allergiesTableView) {
//prepare and return the appropriate cell for *this* tableView
}
return nil; //because you don't expect any other tableView to call this method
}

My suggestion would be to set a tag on both of your table views and then in your tableview dataSource methods check for which the tag the table view your are in. So for instance some where in your code you can do:
myFirstTableView.tag = 1;
mySecondTableView.tag = 2;
later when your are in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.tag == 1)
cell.textLabel.text = #"HI JAZZY";//[RxDict objectAtIndex:indexPath.row];
if (tableView.tag == 2)
cell.textLabel.text = #"BYE JAZZY";
}
Also if you have 2 tableviews with different sizes you can achieve this like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView.tag == 1)
return 1;
else if (tableView.tag == 2)
return 2;
}

One approach I don't see implemented too often is actually to use a NSObject subclass to act as the delegate and datasource for each table, not the view controller. It removes the need for the "if (tableView == someTable) ..." code, and might make both your view controller and UITableView code maintainable and readable.
You'd create an NSObject subclass for each table. These subclasses would contain the desired implementation of your UITableView datasource and delegate methods. You'd then instantiate one of each in your view controller and hook each up to its appropriate table.

Problem 1:
tableView = self.mySecondTextView;
cell2.textLabel.text = #"I love Jazzy :D";
return cell2;
What you are doing here is always returning cell2, setting its text "I love jazzy :D" so it will always fill the first table view because you would not have set the tableView=mySecondTextView before entering into the method. The delegate is always targeting firstTableView.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
Problem 2:
if (tableView == self.myFirstTextView ) {
cell.textLabel.text = #"HI JAZZY";
//[RxDict objectAtIndex:indexPath.row];
//for printing in first table view return cell here like
return cell;
}
if (tableView == self.mySecondTextView) {
cell.textLabel.text = #"BYE JAZZY";
//[RxDict objectAtIndex:indexPath.row];
//for printing in second tableview return cell two here
return cell2;
}
Make sure the table you want to target is set before entering into this function. You can set it in numberofsection method, the view didload method or somewhere else from where you want to show or target table view (like clicking on some button). But you can't set it here.

Related

trying to create different cells in same table view - but can't figure out how to code in the tableviewcontroller

I have created a tableview with multiple prototype (4) cells in order to display different content in each cell but being a newb - I am not clear on how to then code this in the tableviewcontroller to pull data into the multiple cells (just using multiple simple arrays with one data point for each label for now to test it) but I can only get the data to populate in the first cell - and not clear how to code to get the data into the remaining cells. I created 4 separate customtableviewcell files as well. Can someone point me in the right direction on how to code so I can get data into the four separate prototype cells? I need it to be able scroll as it won;t all fit on the the screen which is why I chose table view to do this - but there will only ever be these four sections in the view (with different data depending on what you pushed to get here) should I not be using tableview? if I should be using something different like a view controller with 4 views instead? will it scroll so the user can see all sections? Thanks in advance for any help and suggestions.
You should assign unique Identifier to the each cell in the Storyboard. Then, you can populate appropriate cells like this:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section)
{
case 0:
{
MyCustomCell1 *cell = [tableView dequeueReusableCellWithIdentifier:#"cell_1"];
// Configure cell
return cell;
}
case 1:
...
default: return nil;
}
}
Consider creating custom subclasses of UITableViewCell to provide handy IBOutlets.
(1) You need 4 cells. So, prepare 4 custom cells by creating subclass of UITableViewCell. You will know how to create custom cell by search on google.
(2) Set number of sections to 1.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
(3) Set desired height for each cell
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch(indexPath.row)
{
case 0:
{
return 40;
}
case 1:
{
return 50;
}
case 2:
{
return 30;
}
case 3:
{
return 45;
}
default:
{
return 0; // Default case
}
}
}
(4) Set contents of each cell. The data will come from your data source i.e. Array or Dictionary.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"CellIdentifier%d%d",indexPath.section,indexPath.row];
if(indexPath.row == 0)
{
CustomCell1 *objCustomCell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(objCustomCell1 == nil)
{
objCustomCell1 = [[CustomCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
objCustomCell1.selectionStyle = UITableViewCellSelectionStyleNone;
}
// Set row specific data here...
NSDictionary *dicObj = [arrYourDataSource objectAtIndex:indexPath.row];
objCustomCell1.myLabel.text = [dicObj objectForKey:#"your key"];
return objCustomCell1;
}
else if(indexPath.row == 1)
{
CustomCell2 *objCustomCell2 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(objCustomCell2 == nil)
{
objCustomCell2 = [[CustomCell2 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
objCustomCell2.selectionStyle = UITableViewCellSelectionStyleNone;
}
// Set row specific data here...
NSDictionary *dicObj = [arrYourDataSource objectAtIndex:indexPath.row];
UIImage *theImage = [UIImage imageNamed:[dicObj objectForKey:#"your key"]];
objCustomCell2.myImageView.image = theImage;
return objCustomCell2;
}
// Do same for remaining 2 rows.
return nil;
}
First do this and then add comment. We will move ahead.

First cell always empty in table. Display only from the second cell - Objective c

I have a table view which display the contacts from array. I setup the table view delegates by follows.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [contactArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ContactCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [contactArray objectAtIndex:indexPath.row];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60.0;
}
But the first cell in the table view always empty. It starts display only from second cell. I thought it may be header view. So I removed the header using the following delegate methods.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 0.0;
}
But still have the problem. I attached the screenshot about this issue.
Any help will be appreciated.
Your TableView is fine and it is working correctly, this is due to some other problem that is included in iOS 7, that automatically scroll insets. To solve this problem, go to your storyboard and select the viewcontroller in which your TableView is and select the ViewController and select the Properties of that ViewController, and uncheck this checkbox, which is read as Adjust ScrollView Insets. See this screen shot,
Your table is correct.Just your table was auto adjusted by the viewController.
You can write self.automaticallyAdjustsScrollViewInsets = NO;
Your Deduction is wrong your first cell isn't missing, but your tableview has started by 64 points down. So change your frame of your tableview or your tableview constraints accordingly.
Tip : Try setting a background colour when you have to debug things like this to clear your doubts.

How to add extra cell in cellForRowAtIndexPath?

For example, I have 3 articles and when I display articles I want to display one more cell before the first one (that would be then 4 total).
I need to display that first article which is not in array and then articles which are in array.
UPDATE
I have tried next:
- (NSInteger)tableView:(
UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return ([arr count] + 1);
}
But my app then crash sometimes and I see over NSLOG then that app enters cellForRowAtIndexPath before I call [tableView reloadData].
This is something you should not really do.
Well, you can cheat the framework by returning a view (from -tableView:cellForRowAtIndexPath:) which would contain 2 subviews: your "first article" cell and the original first cell; don't forget to modify -tableView:heightForCellAtIndexPath: as well (otherwise your view would get cut).
But in general, you should change you data model behind the table view to dispay 4 cells – this is just a more valid approach.
You can do like this :
Return an additional row using this method :
// Each row array object contains the members for that section
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [YouArray count]+1;
}
At the end check for this added row :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Create a cell if one is not already available
UITableViewCell *cell = [self.mContactsTable dequeueReusableCellWithIdentifier:#"any-cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"any-cell"] autorelease];
}
//Identify the added row
if(indexpath.row==0)
{
NSLog(#"This is first row");
}
else{
// Write your existing code
}
}
You need to add a extra value in the array using insertObject
[arr insertObject:[NSNull null] atIndex:0];
And implement the methods like:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arr count];
}
- (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];
}
if([arr onjectAtIndex:indexPath.row] == [NSNull null])
{
// 1st cell extra cell do your stuff
}
return cell;
}
Do you keep all your articles in an array? You should add the new article to the array too. The array is your datasource. I take it that you'd want to insert the new article as the first element in your array if you'd like it to appear in the top cell. As soon as you've updated your array you should call [mytableView reloadData] which triggers all the datasource methods to be called and reload your table's data.

Creating Grouped UITableview with Different Cell Types

I need to create a grouped uitableview that includes some sections and possibly different cell types in each sections.
I am trying to create something like old foursquare app, user page (includes 'leaderboard', 'friend suggestions', 'friends', 'stats', 'most explored categories' ... sections).
I am fairly new to ios programming, so that view may not be a grouped uitableview.
What I especially stuck is creating different cells for sections, and finding out which cells are clicked.
My data source will be 2 different NSArray* that consists of different data types, that's why I need different custom cells.
Since you have two different sets of data and you need to display both in different sections, you have to split the data source methods into two.
Basically, choose which dataset you want to be first and off you go.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section)return secondArray.count;
//Essentially, if statements evaluate TRUE and move forward if the inside is 1 or greater (TRUE == 1)
return firstArray.count;
//If the first if statement return hits, then the code will never reach this statement which turns this into a lighter if else statement
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section)
{
//do stuff with second array and choose cell type x
}
else
{
//do stuff with first array and choose cell type y
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get the cell with: UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(indexPath.section)
{
//perform action for second dataset
}
else
{
//perform action for first dataset
}
}
For headers, you can use either of these methods and just keep the same type of styling as above:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
You can create multiple custom subclasses of UITableViewCell, and in the tableView:cellForRowAtIndexPath: method for your UITableViewDataSource, you can use if-statements to determine what type of cell to use.
For example, here's a rough outline of what I might do:
-(UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//First, determine what type of object we're showing
if (indexPath.section == 0) {
//Create and return this cell.
} else if (indexPath.section == 1) {
//Create and return this cell.
}...
}
Here's how you'd implement numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return [firstSectionArray count];
} else if (section == 1) {
return [secondSectionArray count];
} ...
}
For didSelectRowAtIndexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
ObjectSelected *objectSelected = [firstArray objectAtIndex:indexPath.row];
//Now you've got the object, so push a view controller:
DetailViewController *dvc = [[DetailViewController alloc] init];
dvc.objectSelected = objectSelected;
[self.navigationController pushViewController:dvc];
} else if (indexPath.section == 1) {
//Same thing, just call [secondArray objectAtIndex:indexPath.row] instead!
}
}

Adding sections in a grouped table view in Xcode

My code is a little different to others, but it works.
I am new to app coding, but I would like to add some of
these into sections:
So some of them have their own group with a small title to each.
But my code looks like this:
and I don't know what to insert to do it right.
(The bottom half of that picture is the pictures in the detail view, that shows up in the detail view when you select something from the table view.)
(I know Xcode shows errors in my code, but it still works. )
Can anyone help me?
You have to implement some UITableView methods and delegate methods (and of course set your class as the delegate of the class) :
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//Here you must return the number of sectiosn you want
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//Here, for each section, you must return the number of rows it will contain
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
//For each section, you must return here it's label
if(section == 0) return #"header 1";
.....
}
- (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];
}
// Set up the cell...
cell.text = // some to display in the cell represented by indexPath.section and indexPath.row;
return cell;
}
With that, you can arrange your data as you want : One array for each section, one big array with sub arrays, ... as you want. Antthing will be ok as far as you can return the wanted values from the methods above.

Resources