UITableView with multiple datasource - objective-c

I have a ViewController that needs to use 2 UITableViews.
1 is always showing, while the other will show up as a popup after you click on a button on the view.
Typically I set the delegate and datasource to the File's Owner. However, since 1 of the UITableViews is in a popup, I'm not sure how to best tackle this.
e.g how do I tackle this part -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
Please advice.

You should have instance variables for both table views declared in your controller:
#interface MyViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
UITableView *mainTableView;
UITableView *popupTableView;
}
In each data source or delegate method, you can check which table view is being passed by the caller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == mainTableView)
{
// Code to create and return a main table view cell
}
else if(tableView == popupTableView)
{
// Code to create and return a popup table view cell
}
}

Related

Error adding UITableView to ViewController on storyboard

On my storyboard I have a ViewController and I want to add a UITableView with 1 section and 2 static cells. That's all I'm doing right now but I get this error when compiling.
Static table views are only valid when embedded in UITableViewController instances
What am I missing?
Look at This question. Basically the same thing.
Any further questions, just ask! :)
Edited stuff:
UITableViewController *controller = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
[self.view addSubview:controller.tableView];
Then all you need to do is adding the UITableViewDataSource in the header file and you need the datasource methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if([indexPath row] = 0){
do something
}else if([indexPath row] = 1){
do something else
}
I think you just have to set datasource and delegate methods of the tableView in your .h file
#interface viewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
and then link it to your tableView in storyboard.
Please notify if it works..

Master Detail Storyboard: Table View not showing cells (Objective-C)

I'm having troubles with the master viewController not showing any cells. This is the situation:
The app uses storyboard.
When the app launches, it goes to the navigationController
A button is pressed and connected to the table ViewController and it's set to "push" to it.
I've added the object and made a cell/detailView or whatever.
For some reason, the cell won't show up!!!
Here's the files:
MasterViewController.h:
#import <UIKit/UIKit.h>
#import "CraftingDetail.h"
#import "Crafting.h"
#class CraftingList;
#interface CraftingMaster : UITableViewController
#property (strong, nonatomic) CraftingDetail *detailViewController;
#property (strong, nonatomic) CraftingList *CL;
#end
MasterViewController.m:
#import "CraftingMaster.h"
#import "CraftingList.h"
#interface CraftingMaster ()
#end
#implementation CraftingMaster
#synthesize detailViewController = _detailViewController;
#synthesize CL;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
self.CL = [[CraftingList alloc] init];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return self.CL.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.CL.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
cell.textLabel.text = [self.CL craftingAtIndex:indexPath.row].Title;
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
DetailViewController.h:
#import <UIKit/UIKit.h>
#interface CraftingDetail : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *Image;
#property (strong, nonatomic) IBOutlet UITextView *Description;
#end
This is an old question, but having an unexpectedly empty table view is a common issue when starting to develop with table views so hopefully this answer will be of use to someone.
Here are some things to check when your table view is devoid of cells and you expected otherwise:
Are your data source object(s) (self.CL in this case) valid? (ie. Are they != nil and point to the correct object?)
Does numberOfSectionsInTableView: return an integer value greater than zero?
Does tableView:numberOfRowsInSection: return an integer value greater than zero?
Here are a couple of problems in MasterViewController.m above that need attention:
InitWithStyle: will not be executed when the view controller is instantiated in a storyboard. Instead, initWithCoder: should be used. I suspect this was the source of JomanJi's pain as this resulted in self.CL not being instantiated. (As an aside, the data source object/property: CL should be instantiated by assigning the value to the _CL ivar directly, not to the property. See "Initializing a property, dot notation" to learn why).
Due to returning (what is likely) the same value for numberOfSectionsInTableView: as tableView:numberOfRowsInSection: (ie. "return self.CL.count;"), the table view will display the same number of sections as there are cells in each section with each sections' cells containing the same data as the other sections. I doubt this effect was what the developer intended. (This is of course unless the count accessor method in CraftingList does something really strange).
Without seeing the code for CraftingList it is impossible to determine exactly what the problem is. However, given the age of the question, I suspect JomanJi has since figured it out on his/her own.

Failing to properly declare/implement UITableViewDataSource methods

I have a UIViewController that I want to use to implement the methods of UITableViewDataSource on. I have this header, FriendsController.h:
#import <UIKit/UIKit.h>
#interface FriendsController : UIViewController <UITableViewDataSource>
#end
Edit: now updated the #interface declaration to:
#interface FriendsController : UIViewController <UITableViewDataSource, UITableViewDelegate>
and this implementation, FriendsController.m:
#import "FriendsController.h"
#implementation FriendsController
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(#"CALLED .numberOfRowsInSection()");
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"CALLED cellForRowAtIndexPath()");
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"FriendCell"];
cell.textLabel.text = #"Testing label";
return cell;
}
#end
When run this gives me a '-[UIView tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x81734d0'. Can anyone see if there is something wrong with my implementation/declaration of .numberOfRowsInSection()?
Edit: I've added a technique for method listing from here and run the view 'unconnected', it outputs the following list:
[<timestamp etc>] Method no #0: tableView:numberOfRowsInSection:
[<timestamp etc>] Method no #1: tableView:cellForRowAtIndexPath:
[<timestamp etc>] Method no #2: numberOfSectionsInTableView:
[<timestamp etc>] Method no #3: tableView:didSelectRowAtIndexPath:
[<timestamp etc>] Method no #4: viewDidLoad
Post scriptum: Both #ThisDarkTao and #Pei got it right, as can be seen in my previous question documenting the visual parts, here.
You need to add UITableViewDelegate to the list of protocols in the interface file, like this: <UITableViewDataSource, UITableViewDelegate>
You also need all of the following delegate methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1; // Number of rows
}
- (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];
}
cell.textLabel.text = #"Test Cell";
return cell;
}
In your xib/storyboard view, you also need to connect the tableview's delegate and datasource connections to the viewcontroller.
If you want your cells to 'do something' when you tap them, you also need to implement the following delegate method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Tapped cell %d",indexPath.row);
}
If you use the Storyboard in your project, you have to set the UIViewController's Class field to be your "FriendsController" on Identity Inspector of your storyboard.
So you can present your UIVIewController to be using your correct class (In this case, FriendController for you).
Pei.

Displaying different content view in the same uiviewcontroller by uitableview indexpath row

I want to show different UIImageView in the same UIViewController depends on which indexpath row was selected in UITableView. I have an unwise approach which was created lots of UIViewController for different UIImageView, But i don't want do this. Is there any smarter approach can fulfilled that. You help is very appreciated.
First add an UIImageView to the UIViewController's view.
Create a NSMutableArray to store UIImageViews, and in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
imageView = [imageViewArray objectAtIndex:indexPath.row];
}

UITableView didSelectRowAtIndexPath method not firing

I placed a TableView on my xib file with the following method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"FIRED THE EVENT");
}
and it doesn't seem to be firing when I click on a cell in the table. Is there something that I'm missing?
Be sure to include UITableViewDataSource, UITableViewDelegate in your .h file