I try to display objects of an array in a tableview.
This is a single screen app, I'm using storyboard.
When running - the tableview appears as an empty grid. the data of the objects is not displayed. what may cause this?
Having 2 required methods numberOfRowsInSection and cellForRowAtIndexPath I suspect the last one.
The .h file contains this row:
#interface MYViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
I set the delegate & datasource via the code as you suggested. still empty grid.
This is my implementation:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [listRecipes.recipeArray count]; }
-(UITableViewCell )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString cellIdentifier = #"ListCellIdentifier"; MYCustomListCell* listCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; NSString* dataString = listRecipes.recipeArray[indexPath.row]; listCell.listName.text = dataString; listCell.imageView.image = [UIImage imageNamed:dataString]; return listCell; }
I try to display data from an array in MVC .
If the array is local - the data is displayed
Can you please advise what to do?
Thank you in advanced.
Always remember to hook up your table's delegate and datasources.
Being a UIElement on a UIViewController that conforms to these two protocols is not enough for Xcode to assume that that UIViewController should be the delegate and/or datasource for the table.
Right click on your tableview, drag from delegate & datasource to your UIViewController.
You can also set these programmatically via:
self.table.datasource = self;
self.table.delegate = self;
And if you're still having trouble after this, you'll have to show us how you're implementing the datasource protocol methods.
Check if your initialisation of tableview delegate and datasource would be before the recipeArray is initialised. In this case you will have to tableView.reload() after the items are added to recipeArray .
Related
I haven't developed any iOS apps in a while. I am fine with both swift and Objective-C but what I find different is adding a UITableView to ViewController. Before, I used to add a UITableView to ViewController, add the required datasource methods and the typical UITableViewCell object, and return the cell in cellForRowAtIndexPath:, which would display empty cells depending on the number of rows I return. Now, I did everything the same, but the UITableView is empty and when I scroll I see the lines but not my cell.textlabel.text value, which I set. It seems now I am supposed to add UITableViewCell to the UITableView and remove the
#pragma-mark TableView Datasource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_formTitles count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell==NULL)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"cell"];
}
cell.textLabel.text=[_formTitles objectAtIndex:indexPath.row];
cell.detailTextLabel.text=#"Kaushik";
return cell;
}
I can't find a simple post online regarding the same.
Can someone post what are the changes in the new iOS 9 in a simple manner?
Thank you
Right..For those of you who are still prefer to add a tableview to a viewcontroller.Here are the steps
In the ViewController drag and drop the tableview.Now instead of the lines which you see in the old Xcode.This time you would see a blank table view with the text " Table View prototype content" in the middle.
We usually create a tableviewcell only we doing anything different like adding more labels or image etc but hereafter it is required to add a tableviewcell in the tableview.Drag and drop a tableview onto the tableview.It will display as protype cells.One can select type of cell here itself as basic,value 1,value 2 or subtitle.Also NEED TO SET THE REUSE IDENTIFIER IN THE STORYBOARD UTILITIES PANEL ON YOUR RIGHT. At the end, you can select the tableview and add the missing constraints.
Implement the typical required datasource methods in your viewcontroller class.
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:#"cell"];
cell.textLabel.text=#"text";
cell.detailTextLabel.text=#"DetailedText";
return cell;
}
The change here is that we dont require the usual if(cell==nil)
{..}
piece of code since we added the prototype cells to the storyboard.
Don;t forget to connect the delegate and datasource of the tableview to the viewcontroller.
This should display the tableview in your viewcontroller but i am getting a space on top of the tableview which i don't know why.Anyway this is how you add a tableview to a view controller using Objective-C language in iOS 9.3.
FYI: Guys if i've missed anything, please mention it in the comments
Thank you
Put tableView to view controller and link it to viewcontroller.
link delegate and datasource of tableview to viewcontroller.
in
viewcontroller.h
#interface ViewController :<UITableViewDelegate, UITableViewDataSource>
in viewWillAppear put
tblService.delegate=self;
tblService.dataSource=self;
and your array elements.
5.Impliment your tableview delegate method and datasource method .
6.be sure you cell identifier equal the one put on storyboard.
this link will help you more to implement your first app and this video.
i am new to iOS, this may seem like a basic question. I have been working through this tutorial and I have no idea how the tableview is connected to the code. The sample project can be downloaded here.
I was my understanding that you need to extend UITableViewDelegate, UITableViewDataSource in the code, then in the storyboard you can drag from the tableview to them.
But what is perplexing is that the sample project does not extend UITableViewDelegate, UITableViewDataSource at all, therefore, how is the tableview in the story board connected to the code ?
Datasource is used to supply data and delegate is used to supply behaviour. UITableView asks your datasource every time it needs data to display. It provides a lot of flexibility for how you choose to represent your underlying data model. You simply define specific methods to use in order to get table information, and iOS can call them when it needs to know something like the number of rows in a section, or the content of a particular row.
You will probably implement your own delegate mechanism in the future. It is a great design pattern which handles interaction/data transfer between objects.
Because, the basic class adopts from UITableViewController
#interface WTTableViewController : UITableViewController
In your storyboard you just ctrl-drag from tableview to viewController and choose delegate and dataSource.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/ you should refer this it will help u alot
If you working with TableViewController, UITableViewDelegate and UITableViewDataSource are connected to table automatically. In case you are working with ViewControler which contains TableView, you have to add UITableViewDelegate and UITableViewDataSource like this: #interface myViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>. In new versions of Xcode you can drag delegate and data source to table, and if you want to set delegate programmatically, you can add this two lines of codes:
[tableView setDelegate:self];
[tableView setDataSource:self];
or, equally:
tableview.delegate = self;
tableview.dataSource = self;
In viewcontroller.h file e
declare the delegate and datasource method.
UIViewController<UITableViewDataSource,UITableViewDelegate>
then
connect the delegate and datasource method with viewController so
in viewController.m file
- (void)viewDidLoad {
tableview.delegate=self;
tableview.dataSource=self;
}
In Objective-C/iOS you often implement things by having classes conform to protocols rather than subclassing classes. WTTableViewController conforms to the protocols
UITableViewDataSource: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/
and
UITableViewDelegate: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/
In MainStoryboard.storyboard you can see in the inspector to the right that the TableViewController has a custom class of WTTableViewController
The relevant methods in WTTableViewController.m:
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"WeatherCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
}
Here's some general info about protocols: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithProtocols/WorkingwithProtocols.html
I suggest reading a beginners book or tutorial on iOS to pick up the overall design principles otherwise many things can be quite confusing.
I'm trying to make a custom UITableView that will store a textLabel and detailLabel in each cell, but all the tutorials I find are for UITableViewController. When I try to implement just the UITableView, I can't figure it out.
I actually will have 2 table views on this view controller. It's almost like a webpage in layout, or at least how I want it.
2 tables, and be able to put anything I want inside each cell. For some, a couple strings, for others, maybe 3 small images.
Here's a screenshot of what I want. I just can't figure out how to configure the tableviews so I can put content in them.
Edit: Im on swift, just FYI, and now have the code below (minus screenshot). It stalls and I get SIGABRT at the declaration of the cell, even though that was the default implementation.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
if (tableView == self.topTableView) {
// do stuff for the first tableView
cell.textLabel.text = "Size"
cell.detailTextLabel.text = "750.32MB"
} else {
//do stuff for tableView2
}
return cell
}
Take a look at the answer to this question for information on the minimum implementations of the table view delegate and datasource protocols.
Since you have two table views, you'll need a way to determine which table view is asking for information. Note that the first argument to all of the table view delegate functions is a pointer to the table view itself. You can compare that with the IBOutlet's to the table view to determine which table view is requesting information.
For example,
#property (weak, nonatomic) IBOutlet UITableView *tableView1;
#property (weak, nonatomic) IBOutlet UITableView *tableView2;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if ( tableView == self.tableView1 )
return 5;
else if ( tableView == self.tableView2 )
return 10;
else
return 0; // should never happen
}
The premise is the same in terms of the tableView delegate methods you need to implement. Assuming you have connected the tableviews to your viewController in IB or storyboard or whatever, just make sure you set the viewController to be the delegate and dataSource of both tableViews, then you need your ViewController to be a UITableViewDataSource and UITableViewDelegate in your interface declaration. Then be sure to implement the appropriate delegate methods and inspect the tableView to determine which one the viewController is working with at the time.
In your header file:
#interface MyViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>
In viewDidLoad:
self.tableView1.delegate = self;
self.tableView1.dataSource = self;
self.tableView2.delegate = self;
self.tableView2.dataSource = self;
In your delegate methods, check which tableView you are working with, something like this:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.tableView1) {
// do stuff for the first tableView
} else {
//do stuff for tableView2
}
return cell;
}
I am making an App that uses a UITableView and UITableViewController. However, when I call [self.tableView reloadData]; in the UITableViewController, nothing happens, (tableView: cellForRowAtIndexPath: is not called). What should I do?
- (void) UserChangedAmmountAndCurrency: (NSNotification*) notification {
self.localBank.activeAmmount=((NSNumber*)[notification.userInfo objectForKey:#"newAmmount"]).doubleValue;
self.localBank.activeCurrency=[self.localBank.worldBank requestCurrencyForLocalBank:((NSString*)[notification.userInfo objectForKey:#"newISO4217Currency"])];
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *ammount= [self.localBank ammountForElementAtIndex:indexPath.row];
VIPCurrency* currency=[self.localBank currencyForElementAtIndex:indexPath.row];
static NSString *CellIdentifier = #"cellWithCurrencyAndAmmount";
VIPConversionCell* cell=[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.longCurencyIdentifier.text=currency.longName;
cell.shortCurrencyIdentifier.text=currency.shortName;
cell.textfieldForAmmount.text=ammount.stringValue;
return cell;
}
EDIT:
I've done some extra testing. Ive tested that the tableview datasource and delegate are the viewcontroller that I use to call the reload method, which was ok. I've also noticed something else weird. When calling reloadData, neither numberOfSectionsInTableView: nor numberOfRowsInSection: is called. I feel like I'm failing to do a basic thing before calling reloadData, but I don't know what. Could it be that I must somehow specifically set cells as out of date?
EDIT: I've also checked that the method was called in the Main Thread, which was also ok
Set table view delegate in .xib file and .h file (UITableViewDataSource, UITableViewDelegate)
[myTableView reloadData];
The idea of checking for nil from dequeReusableCellWithIdentifier call is to create a new cell and return it. Unless you created a cell with the given identifier before and is in reusable pool, that method will return nil. So, as #Verec mentioned, you should check for nil and create the cell yourself and return.
You just need to add
UITableViewDataSource,UITableViewDelegate
in .h
example
#interface yourviewcontroller : UIViewController <UITableViewDataSource,UITableViewDelegate>
I used IB to create a UITableViewController in Storyboard. And I set the UITableview's delegate to be its controller. The UITableView has static cells. Just 2 sections. First section has 3 non-selectable rows. And last section has 1 row which is selectable. I set this all in IB only.
Then I implemented this method in the UITableViewController.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"SELECTED");
if (indexPath.section == 1 && indexPath.row == 0) {
//login and report the result
[self login];
}
}
When I select the only row in the 2nd section, this above method is not getting called. What could have gone wrong. I have double checked the delegate setups in outlets inspector of UITableView as well. Everything is fine!
Do you see the NSLog statement in the console? How about in viewDidAppear, NSLog(#"Delegate: %#",tableView.delegate)
See if you're getting NULL in the console.
You know that the dataSource is connected right, or else you wouldn't have any cells visible. It's got to be your delegate connection =)
Just do this:
Control drag you tableView from Storyboard to viewcontroller .h file, create #property for ex. tableView. Add again to .h file. Then in .m file in
viewDidLoad write this:
-(void)viewDidLoad{
//your other code
self.tableView.delegate = self;
self.tableView.dataSource = self;
//other code ...
}
I prefer to use tblView for property name, because you will see warning that tableView hides instance. Hope this help.