UITableView is not reloading - ios

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>

Related

Adding UITableView to ViewController

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.

UItableview inside antother UItableviewCell

I want a tableview inside another tableviewCell like the following image.It shows one complete cell with a few details and a tableview. How can i do this?I was following this link Link.This is an old code .It is using xibs.I dont have any idea where to set the delegate for the inner tableview.Please help.Any suggestion will be realy helpfull.
My first idea would be:
Subclass UITableViewCell ("MainTableViewCell") and extend it with UITableViewDelegate and UITableViewDatasource.
Next to all the properties you need in "MainTableViewCell" add a TableView "tableViewFilms" and an array "films" for the Films. Also don't forget to add the datasource methods for a tableview to the implementation file.
To easily setup a cell I add a setup-method to the header-file. Which can be called once the cell is instantiated. You can modify it as you want, give it as many parameters as you want and in the implementation (see step 4) set datasource and delegate of your inner tableview.
- (void)setupCellWithDictionary:(NSDictionary *)dict AndArray:(NSArray *)filmsForInnerTable;
You can call this method in your datasource method, once a cell is instantiated:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MainTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainTableViewCell" forIndexPath:indexPath];
NSDictionary *dict = (NSDictionary *) allDataDictionaries[indexPath.row];
[cell setupCellWithDictionary:dict AndArray:filmsForInnerTable];
return cell;
}
Subclass UITableViewCell another time: "FilmTableViewCell"
When setting up the a Cell of "MainTableViewCell", set the delegate and the datasource of "tableViewFilms" to self (object of "MainTableViewCell").
- (void)setupCellWithDictionary:(NSDictionary *)dict AndArray:(NSArray *)filmsForInnerTable{
self.films = filmsForInnerTable;
self.tableViewFilms.dataSource = self;
self.tableViewFilms.delegate = self;
[self.tableView reload];
//more instructions
}
Populate the tableview with the data from the array "films" using "FilmTableViewCells".
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
FilmTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"FilmTableViewCell" forIndexPath:indexPath];
Film *film = (Film*)films[indexPath.row];
[cell setupCellWithFilm:film];
return cell;
}
Hope this helps.
Don't forget to use Outlets, the method definitions and to set the reuse-identifiers for the cells!
Check my answer in this ios 8 Swift - TableView with embedded CollectionView. You have replace that UICollectionView with UITableView.
Everything else is pretty much the same. Its just a head start with UITableView and UICollectionView created programmatically.
I can change it accordingly if you don't understand.

UITableView reloadData not working when put it in Editing Did End IBAction, btter know why

I put a textfield in every cell of the table. And after editing the textfield, an EditingDidEnd Event will trigger. In the method of hanlding this event I try to use
[XXXUITableViewController.tableView reloadData];
but it doesn't work(the delegate method is not called).
If I try to reloadData in someway like hanlding Tapgesture, it works just fine. I can use anthoer way to make my app work, but it's better to know why is reloadData not working. Any ideas, thanks a lot.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ParCellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
for(UIView * old in cell.contentView.subviews){
[old removeFromSuperview];
}
//add a textfield in Table Cell View
ParticleConfigCellView * parCell=[[[NSBundle mainBundle] loadNibNamed:#"ParticleConfigCellView" owner:self options:nil]objectAtIndex:0];
[parCell refreshFromDataSource:[self.dataContainer.data_particleConifig objectAtIndex:indexPath.row]];
[cell.contentView addSubview:parCell];
return cell;
}
- (IBAction)nameChange:(id)sender {
[self savedata];
[self.tableView reloadData];//(not working. Table view delegate methods are not called.)
}
Here in this method also reload your array which is showing in table view because after saving new data you are not reloading new data so that its showing old data only.
- (IBAction)nameChange:(id)sender {
[self savedata];
[yourArray removeAllObjects];
//then here put new that in yourArray
[self.tableView reloadData];//(not working)
}
Edit:
Also call this method [self.tableView reloadData]; in the last line of your savedata method.
Each time you create a cell, you must assign a delegate text field that is in it. If you are using a dynamic table, add this code cell.yourTextField.delegate = self in this method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath.
Or maybe you forgot to subscribe your class to the protocol?
In any case, the method reloadData updates the data in the table from its data source, and I do not understand why you need to call this method after you enter text in a field that is in the table. If you don't save this text, it will disappear after call reloadData method.

empty grid of UItableView using storyboard

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 .

Fails to call delegate/datasource methods in UITableView implementation

I have created .h and .m files for UITableView called mainTableViewgm.h and mainTableViewgm.m resp. and I am calling -initWithFrame: method from my main view controller to this mainTableViewgm.m implementation file
[[mainTableViewgm alloc]initWithFrame:tableViewOne.frame]
Note that this tableview is in my main view controller. But I have created separate files for the tableView and have also set the custom class to mainTableViewgm in storyboard.
the -initWithFrame: methods appears as follows
- (id)initWithFrame:(CGRect)frame
{
//NSLog(#"kource data");
self = [super initWithFrame:frame];
if (self)
{
[self setDelegate:self];
[self setDataSource:self];
[self tableView:self cellForRowAtIndexPath:0];
[self tableView:self numberOfRowsInSection:1];
// Initialization code
}
return self;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"kource data");
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"kource data2");
UITableViewCell*cellOne =[[UITableViewCell alloc]init];
cellOne.detailTextLabel.text=#"text did appear";
return cellOne;
}
the -initWithFrame: is being called fine along with the 'if (self)' block in this method. But the problem is numberOfRowsInSection: and cellForRowAtIndexPath: are not being automatically called here . kource data/kource data2 never appear in log. What do I do to load the table? Are the delegate/datasource being set incorrectly?
I must mention that I have also set the UITableViewDelegate and UITableviewDataSource protocols:
#interface mainTableViewgm : UITableView <UITableViewDelegate,UITableViewDataSource>
#end
Help will be much appreciated. Thank you.
Your tableview is not loaded when the controller is initializing, so you cannot do that in the init methods. You have to move your code to the viewDidLoad method.
Also you are not setting the delegate and datasource on the tableview object (probably a type, you are setting them on the view controller). It should look like this:
- (void)viewDidLoad:(BOOL)animated {
[super viewDidLoad:animated];
[self.tableView setDelegate:self];
[self.tableView setDataSource:self]; // <- This will trigger the tableview to (re)load it's data
}
Next thing is to implement the UITableViewDataSource methods correctly. UITableViewCell *cellOne =[[UITableViewCell alloc] init]; is not returning a valid cell object. You should use at least initWithStyle:. And take a look how to use dequeueReusableCellWithIdentifier:forIndexPath:. A typical implementation would look like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
// Reuse/create cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Update cell contents
cell.textLabel.text = #"Your text here";
cell.detailTextLabel.text=#"text did appear";
return cell;
}
I can't believe I've been doing XCode programming for two years, and still hit this issue.
I had the same problem with XCode 6.1 - I was setting my UITableView's delegate & dataSource in the viewWillAppear function, but none of the delegate functions were kicking in.
However, if I right-clicked on the UITableView on the Storyboard, the circles for delegate and dataSource were empty.
The solution, then, is to hold down the CTRL key, and drag from each of these circles up to the name of your UIView which contains your UITableView:
After doing this, my UITableView happily populated itself.
(So, we're upto v6.1 of XCode now are we ? Do you think Apple ever going to make this thing, you know, friendly...? I would quite like to add a Bookmark in my code... that'd be a nice feature.)

Resources