2 Table Views on One Page - Two NSArrays - iphone

Hello I am brand new to xCode and iPhone development. I have two different TableView controls on one page. I have NSArray #1 that needs to be the datasource of TableView #1 and NSArray #2 that needs to be the datasource for TableView #2.
The only trouble is that NSArray#1 populates both TableView1 and TableView2. I looked through the code and can't seem to find where you can distinguish which NSArray belongs to each TableView.
Any help will be appreciated. Thanks in advance!
#interface GrainBinContentsEstimatorViewController : UIViewController
<UITableViewDelegate, UITableViewDataSource>
{
UITableView *tableViewGrainBinType;
UITableView *tableViewGrainType;
}
#property (strong, nonatomic) NSArray *arrayGrainBinTypes;
#property (strong, nonatomic) NSArray *arrayGrainTypes;
#property (nonatomic, retain) UITableView *tableViewGrainBinType;
#property (nonatomic, retain) UITableView *tableViewGrainType;
#implementation GrainBinContentsEstimatorViewController
#synthesize arrayGrainBinTypes, arrayGrainTypes, tableViewGrainBinType, tableViewGrainType;
- (void)viewDidLoad
{
[super viewDidLoad];
self.arrayGrainBinTypes = [[NSArray alloc]
initWithObjects:#"RF", #"RC45", #"RC60", nil];
self.arrayGrainTypes = [[NSArray alloc]
initWithObjects:#"Wheat", #"Corn", #"Soybeans", #"Rice", #"Milo", #"Barley", nil];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return #"Select Bin Type";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.arrayGrainBinTypes 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];
}
cell.textLabel.text = [self.arrayGrainBinTypes objectAtIndex: [indexPath row]];
return cell;
}

In every delegate method (callback) the caller (tableview) is passed as a parameter. So you can switch based on this parameter like:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
   if (tableView == self.tableViewGrainBinType) return [self.arrayGrainBinTypes count];
else return [self.arrayGrainTypes count];
}
You get the idea...

First of all, welcome to SO.
So, you have a reasonable design concept here: One array populates one table view. The data source/delegate of your table view is typically a UITableViewController or UIViewController, but it certainly doesn't have to be. In your case, it's your UIViewController. So, what happens is that when each table view loads, it asks its data source "Hey, how many rows/sections do I have? What do my cells look like?" and other questions.
In your case, you're not distinguishing between table views! So tableView1 is asking "what do my cells look like? Let's see what tableView:cellForRowAtIndexPath: has to say!" and you're giving it info from your arrayGrainByTypes array. Then tableView2 comes along and asks the same question, and uses the same method to get its answer. In each of these data source methods, you are typically given, as an argument to the method, which table view is asking for this information. So, just check which table view is asking!
if (tableView == self.tableViewGrainType) {
// table view 1's information is set here
else if (tableView == self.tableViewGrainBinType) {
// table view 2's information is set here
}

Related

Loading data into a uitableview in a uiviewcontroller

I am trying to load data from an array which was made by parsing json... I have the json data in the arrays for sure, but the table view methods are not even being called... I have the table view embedded in a regular uiviewcontroller, it compiles and everything the table just loads no data.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [transactions count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"any cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"any cell"] autorelease];
}
NSLog(#"got here");
cell.textLabel.text = [names objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [prices objectAtIndex:indexPath.row];
return cell;
}
- (void)viewDidLoad
{
[super viewDidLoad];
names = [[NSMutableArray alloc] init];
prices = [[NSMutableArray alloc] init];
[self requestTransactionData];
}
And here's my .h file...
#interface Controller1 : UIViewController
<UITableViewDelegate, UITableViewDataSource>
{
UIActivityIndicatorView *loadingIndicator;
IBOutlet UITableView *myTableView;
IBOutlet UILabel *totalLabel;
NSMutableArray *names;
NSArray *transactions;
NSMutableArray *prices;
}
#property(nonatomic, retain) IBOutlet UIActivityIndicatorView *loadingIndicator;
#property(nonatomic, retain) IBOutlet UILabel *totalLabel;
#property(nonatomic, retain) UITableView *myTableView;
I can't use ARC for this project. I also have it hooked up properly in the interface builder... These seems rather easy but for some reason I can't figure it out. Any suggestions?
Thanks
I don't see how you know the data source methods are not being called. You are not logging all of them. IfnumberOfRowsInSection is called before transactions is populated or is nil, it returns zero and that's the end of that.
Try calling reloadData using delayed performance so that it happens after transactions is populated. The table view doesn't magically know when your data is ready; you have to tell it.
call sef.tableView reloadData after names the prices were filled in requestTransactionData

Trouble Reloading UITableView

I am trying to create an iphone application that reads a json feed and I am having some trouble updating a TableView.
This is my TableViewController header file:
#interface LiveNewsController : UITableViewController <UITableViewDelegate, UITableViewDataSource>{
NSMutableData *responseData;
NSMutableArray *articleArray;
UITableView *tblView;
}
-(void) refreshPressed: (id)sender;
#property (nonatomic, retain) IBOutlet UITableView *tblView;
#end
These are some parts of my TableViewController implementation file:
#implementation LiveNewsController
#synthesize tblView;
-(id) init {
if(self = [super init])
{
self.title = #"Live News";
}
return self;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"I am here %d",[articleArray count]);
return [articleArray count];
}
// Customize the appearance of table view cells.
- (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] autorelease];
}
NSLog(#"cellForRowAtIndexPath called. Data size %d", [articleArray count]);
NSUInteger row = [indexPath row];
cell.textLabel.text = [articleArray objectAtIndex:row];
return cell;
}
-(void) refreshPressed: (id)sender
{
NSLog(#"Reload Pressed. Data size: %d", [articleArray count]);
[tblView reloadData];
}
Here is a screenshot of my .xib file with the connections:
So the main idea is the following:
Fetch articleArray
When refresh is pressed update view (the data is being fetched correctly but the snippet doesn't show it here)
numberOfRowsInSection and CellForRowAtIndexPath are only being called once when the view loads but nothing happens when I press the reload button.
I checked tblView and it is nil. I did some research and read that this is usually caused by some erroneous connections in the .xib file but I have triple checked that and I can't seem to pinpoint the problem.
Any help is appreciated,
Thanks!
You don't need to declare the UITableView tblView, the UITableViewController has already one (and therefore all subclasses too).
Just try [self.tableView reloadData];.

cellForRowAtIndexPath never called

I've subclassed UITableView to create my own data retrieval system, as described in Apple's own Core Data tutorial, but I've hit a problem. The substitute cellForRowAtIndexPath method in my custom table never gets called, not even when I call reloadData or setNeedsDisplay. I've been hunting around for solutions to this one, and it seems that this error can be caused by a multitude of problems. However I've checked all the ones I can find and cannot see anything missing. Can anyone tell me what's likely to be wrong?
P.S. I know the UITableViewDataSource protocol needs to be in triangular brackets, but I couldn't find out how to show triangular brackets on the page without deleting the text between them.
H-File
#interface DataTable : UITableView <UITableViewDataSource> {
NSMutableArray *list;
}
#property (nonatomic, retain) NSMutableArray *list;
#end
M-File
#implementation DataTable
#synthesize list;
-(id) initWithFrame:(CGRect)rect Style:(UITableViewStyle)style{
if (self = [super initWithFrame:rect style:style]){
list = [[NSMutableArray alloc] init];
self.dataSource = self;
}
return self;
}
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [list count];
}
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellID = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:cellID] autorelease];
}
CH *this = (CH *)[list objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [this.clusterName mutableCopy];
return cell;
}
-(void) dealloc{
[list release];
[super dealloc];
}
#end
Never mind, think I've found it. Basically, you can't set the datasource delegate in that part of the program. Need to do it from its owning view controller.

Add an external TableView inside a small view on the Main Screen

I have a simply MainWindow file created by the Interface Builder in black background. Inside this plain view, I've added from top to bottom a small view (300x100), a textLabel and a couple of buttons.
In the MainApplication.h I've defined:
IBOutlet RoundRectView* smallView;
IBOutlet UILabel* label;
In the MainApplication.h I've #synthesized these variables and with that:
[label setText:#"Test"];
I can see all in my screen and it works perfect.
Now my problem:
I want to add a table with two rows inside my small white view, and what I've done is:
Create a tableController.h who's the delegate and the data source:
#interface IncomeExpenseController :
UITableViewController
{ IBOutlet
UITableView* smallTable; NSArray
*content; }
#property (nonatomic, retain)
UITableView *smallTable; #property
(nonatomic, retain) NSArray *content;
#end
Create the .m file with:
#synthesize smallTable; #synthesize
content;
(void)viewDidLoad {
[super viewDidLoad]; content = [[NSArray alloc]
initWithObjects:#"Item1", #"Item2",
nil]; }
(NSInteger)numberOfSectionsInTableView:(UITableView
*)tableView {
// Return the number of sections.
return 0; }
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 2; }
// Customize the appearance of table
view cells.
- (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]
autorelease];
} NSLog(#"inside cell");
// Configure the cell... cell.textLabel.text = [content
objectAtIndex:indexPath.row];
return cell; }
Now in the Interface Builder, I drag and drop a UITableView inside the white small view and drag and drop a Table View Controller along with the File Owner's window and I do these connections:
Class of the Table View Controller to tableController
Outlets:
DataSource and Delegate to my Table Controller
Referencing Outlets:
customTable and View to my Table Controllers
When I execute, I can see the lines of the table view but with no content, I cannot see the NSLog either but if I put a NSLog inside the viewDidLoad I can see it.
I'm really new (2 days) on that and any help would be really appreciated.
Thanks!
Solved.
First of all, the TableView is grouped so I must return almost one section.
Second, from the Interface Builder, I had to link the "view" from the Table to my external controller.
Now it works perfectly.

iPhone: UITableView, Dragging Table Contents Causes Crash

I'm new to iPhone application development. I'm trying to understand how to use UITableView.
I'm wrote simple code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1 ;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
cell.textLabel.text = #"Hello";
return cell;
}
UITable shows content, but if i'm drag table contents my application terminates. You can see video: http://www.youtube.com/watch?v=TucTVJVhSD0
I tried to everything with array:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1 ;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [hello count] ;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
cell.textLabel.text = [hello objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSLog(#"Selected") ;
}
- (void) awakeFromNib
{
hello = [[NSArray alloc] initWithObjects:#"hello", #"world", #"end", nil];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
Content is shown and if I'm selecting item I'm getting:
[Session started at 2010-03-16 19:21:48 +0200.]
2010-03-16 19:21:52.295 ViewTest[1775:207] *** -[ViewTestViewController respondsToSelector:]: message sent to deallocated instance 0x3911ec0
I'm total new to iPhone programming. And as I see everything I do - I'm just getting application terminated ..
Your table view code looks fine. Did you implement any other delegate methods in the ViewTestViewController?
Try running the application in the debugger. When it crashes, look at the stack trace. It should give a better hint.
(1) I think you may have released your tableview controller instance and killed it while it was still in use so that when the tableview sends it one of its delegate or datasource messages it crashes.
(2) Alternatively, the error message says that you are attempting to send the respondsToSelector: message to an instance of ViewTestViewController when you should be sending it to the class. (-[ViewTestViewController respondsToSelector:] vs + [ViewTestViewController respondsToSelector:] the "-" and "+" make all the difference.)
So, somewhere in your code, probably your app delegate, you've got code that says:
ViewTestViewController *myTableViewController= //..however you setup the controller
[myTableViewController respondsToSelector:#selector(someMethod)];
...when you should have...
[ViewTestViewController respondsToSelector:#selector(someMethod)];
I think (1) the most likely.
Thanks to all. I found problem. I found i haven't connected viewController IBOutlet with App Delegate. But why View was shown ?
#interface ViewTestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
ViewTestViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet ViewTestViewController *viewController;