Hide Null UItableView Cells/Rows - ios

I currently have a uitableview in place.
The data is obtained from an sqlite file.
Each column of the sqlite file will represent a list of: labels, images etc
The code i am using to get rows is
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
AppDelegate* appdelegate = (AppDelegate*) [[UIApplication sharedApplication]delegate];
return [appdelegate.arrayDatabase count];
}
The code to populate the cells
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"simpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == Nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
AppDelegate * appdelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
ShowsList *sShows = [appdelegate.arrayDatabase objectAtIndex:indexPath.row];
cell.textLabel.text = [sShows strName ];
}
The problem i am having:
I want to use the labels column to populate the cell text of ViewController1.tableview but it is returning the null rows and displaying empty rows/cells in the view.
However I want to hide the rows by either counting the null cells and applying the count to the numberOfRowsInSection: method or by simply hiding empty cells.
Hide empty cells in UITableView & How to hide a section in UITableView? looks like something similar but didn't resolve my issue.
Could somebody please point me down the correct path or provide the answer :)
Thanks so much
Thomas

Add this code
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
   
   
   return [[UIView alloc]init];
   
}
OR
There is alternate solution
you can set height of UITableView in numberOfRowsInSection function, having height as [array count]*(cell height)
Hope it helps you..

just implement a reloadTableData method like that
- (void)reloadTableData
{
// do a reload maybe from db and get yourobjects eg dbItems
// _tableItems = [NSMutableArray array];
for (ShowsList *list in dbItems) {
if ([list strName].length) {
[_tableItems addObject:list];
}
}
}
then just use _tableItems array to populate your tableview
use [self reloadTableData] instead [self.tableview reloadData]
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _tableItems.count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"simpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == Nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
ShowsList *sShows = [_tableItems objectAtIndex:indexPath.row];
cell.textLabel.text = [sShows strName ];
}

You should create a mutable copy of your data object. Iterate to it first. Remove null/blank entries. Now use this modified collection for tableViewDelegate methods.

Assuming you are getting #"" in the model from which you are populating the UITableView.
You can remove that blank like this:
[_arrays removeObjectIdenticalTo:#""];
And use this filtered array as your model to populate the tableview.

In your viewDidLoad set the table footer as:
[yourTableView.tableFooterView setFrame:CGRectMake(0, 0, yourTableView.frame.size.width, 1)];
The footer is not used. But making its frame to sizeZero might crash the application, so use footer with height 1.
This worked for me.
Hope it helps.

Related

Single Array Value to show multiple tableview on one viewController

I am developing Iphone Application.Using Three table view on Single viewcontroller. value show on those tableview's on single array but problem is that those array value show on first tableview not on other two tableview's. please help Thanks in advance
code..
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_arrayResult 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];
}
MEObject *obj = [_arrayResult objectAtIndex:indexPath.row];
if (tableView == _tableView) {
cell.textLabel.text= obj.emp_client_name;
}
if (tableView == _secondTableView) {
cell.textLabel.text= obj.emp_event_name;
}
if (tableView == _thirdTableView) {
cell.textLabel.text=obj.emp_client_name;
}
return cell;
}
Please cross check if you are setting datasource and delegates of all 3 tables to viewcontroller.
When you set your _arrayResult, you need to reload all 3 table view
_arrayResult = #[a,b,c];
[table1 reloadData];
[table2 reloadData];
[table3 reloadData];
After once you set the datasource/Delegate to the all three tableview. I haven't seen any datasource allocation as per your tableview. Like
if tableview == tableview1 {
Return first array
}
Can you please try giving name to those tableview on outlet and then for each datasource and delegates function call as per your requirement but before check which tableview is displayed.

The first cell of UITableView is blank (TableView in UIView)

I have the following code to create my cells in a UITableView.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"futureAppointments";
FutureAppointmentsViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (nil == cell) {
[tableView registerNib:[UINib nibWithNibName:#"FutureAppointmentsViewCell" bundle:nil] forCellReuseIdentifier:CellIdentifier];
cell = [[FutureAppointmentsViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
NSUInteger position = indexPath.row;
cell.appointmentDescription.text = [NSString stringWithFormat:#"%lu. %#. %#", (unsigned long)position, #"Steve", #"10/03/"];
return cell;
}
The problems is, the first cell of the tableView is missing. It should start with 0. Steve but instead starts with 1. Steve. Also there are only 4 elements in the list instead of 5.
When I place a break point in the code, the first cell is nil.
Does anyone know what might be happening?
Put this line of code:
[tableView registerNib:[UINib nibWithNibName:#"FutureAppointmentsViewCell"
bundle:nil]
forCellReuseIdentifier:CellIdentifier];
In viewDidLoad. It doesn't belong in cellForRowAtIndexPath. Once you do this then you no longer need to check whether the cell is nil.
Change cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"futureAppointments";
FutureAppointmentsViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSUInteger position = indexPath.row;
cell.appointmentDescription.text =
[NSString stringWithFormat:#"%lu. %#. %#",
(unsigned long)position, #"Steve", #"10/03/"];
return cell;
}
I think I had similar problem when I was using UITableView inside UIView and initialized it in init method.
I was not able to find good explanation for that behavior, but I've found tricky solution for that - I was reloading UITableView instance from UIViewController in viewDidAppear method.
I would also like to know, why UITableView is not drawing all UITableViewCell.

Adding Admob ads to UITableView

This is the original code. I am a beginner in iOS development, how should I modify the code such that Admob ads will be loaded at the bottom of tableview? I tried to follow the tutorial from http://jmsliu.com/1207/add-google-admob-in-ios-apps.html , but can't get it to work.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.prefixArray 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] autorelease];
}
NSDictionary *d = self.prefixArray[indexPath.row];
cell.textLabel.text = d[kMDTitleKey];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *d = self.prefixArray[indexPath.row];
NSInteger entryID = [d[kMDIdentifierKey] integerValue];
self.searchBar.text = d[kMDTitleKey];
[self.db fetchDefinitionsWithID:entryID callback:^(NSDictionary *response) {
NSString *HTML = [self.HTMLRenderer renderHTML:response];
[self.webView loadHTMLString:HTML baseURL:nil];
[self.searchDisplayController setActive:NO animated:YES];
}];
}
The tutorial you share uses the UITableView's title header to show an ad. Probably that's not a good idea since you'll probably would need to use those headers for your own purposes.
I understand you want to put ads at the bottom of the screen. In that case it would be a good idea to use an UIView below UITableView. In that case you'll need to change your UITableViewController for an UIViewController to be able to do that.
If you want to add the add at the bottom of the UITableView you should think of it as the cell N+1 (being N the size of self.prefixArray) and update your table callbacks to handle the special case correctly.
You should add the advert view as the footerview for the tableview. Implement
(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
where you will create the advert view and return it as the footer view
dont put the advert view inside a cell, as it will be dequeued and its just the incorrect place for it.

Several cells in UITableView

I'm seeking how create several cells to go to different ViewControllers.
For my TableView, I'm using a subclass of UITableViewController.
And when I choose 2 in the following method, I just see 2 identical cells which are doing exactly the same thing. I'm not interested by this. I don't even know their IndexPath in order to change their title.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 2;
}
And When I try to put another UITableViewCell in my TableView, it doesn't appear on iOS simulator, even with the same option (same subclass) than my first UITableViewCell which I can see.
Thanks for your help.
Edit : Here is my new code to create 2 cells but doesn't work :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell2";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[customCell alloc] init];
}
static NSString *CellIdentifier1 = #"Cell1";
UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell1 == nil) {
cell1 = [[customCell alloc] init];
}
// Configure the cell...
return cell;
}
You define your cells in tableView:cellForRowAtIndexPath:, so you should provide an implementation for that method.
tableView:numberOfRowsInSection: only returns the number of cells in the table.
If you need more help, please provide your implementation for tableView:cellForRowAtIndexPath:. This is how a typical implementation looks like:
- (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];
}
... customize your cell ...
}
EDIT:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell2";
static NSString *CellIdentifier1 = #"Cell1";
if(indexPath.row == 0 ) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[customCell alloc] init];
}
} else {
UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell1 == nil) {
cell1 = [[customCell alloc] init];
}
}
return cell;
}
This method gets called when a cell has been selected. You can decide what you wanna do according to the selected row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0)
[self goToFirstViewController];
else
if(indexPath.row == 1)
[self goToSecondViewController];
}
Use the following:
- (NSInteger) tableView: (UITableView*) tableView numberOfRowsInSection: (NSInteger) section
This delegate method returns the number of rows you want in that particular section. So if you want more than 2 rows, or you want the number of rows to be dynamic, you can create a NSArray in the AppDelegate or in the init method of the viewController class, and return the number in the numberOfRowsInSection method like
return [delegate numberOfNames];
In my example above, I created an array in my AppDelegate and also a method to return the number of objects I have in that array so that I can create the number of rows for my table.
- (UITableViewCell*) tableView: (UITableView*) tableView cellForRowAtIndexPath: (NSIndexPath*) indexPath
This delegate method will show what you want to display in each cell. Therefore, following on from my array created in my AppDelegate, I first create the cell, then I will set the text I want to display on the cell with a method I created in my AppDelegate that will return a NSString while taking in a NSInteger so that I can loop through my array and display the text accordingly.
static NSString* MyIdentifier = #"Default";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if( cell == nil )
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
cell.textLabel.text = [delegate nameAtIndex:indexPath.row];
}
nameAtIndex is the name of the method I created in my AppDelegate that will return the NSString object at the specific index (ie. the row number) from the NSArray I created to store all the items of my table.
When the user clicks on any of the rows in the table created, this delegate method will be called
- (void) tableView: (UITableView*) tableView didSelectRowAtIndexPath: (NSIndexPath*) indexPath
And in here, I will check if the text displayed matches any of the items in my array from the AppDelegate that stores the items in the table, and create the view that is necessary.
UIViewController* viewController = nil ;
NSString* nameInArray = [delegate nameAtIndex:indexPath.row] ;
if( [nameInArray isEqualToString:#"firstName"] )
{
viewController = [[FirstViewController alloc] init];
}
else if( [nameInArray isEqualToString:#"secondName"] )
{
viewController = [[SecondViewController alloc] init];
}
else if( [nameInArray isEqualToString:#"thirdName"] )
{
viewController = [[ThirdViewController alloc] init];
}
So with these 3 delegate methods, you will be able to create the table using a NSArray created, and be able to redirect the user to a viewController according to which option in the table he chooses. You will not have to keep editing the delegate methods if you choose to add more rows to the table as well since you are returning the count of the array when setting up the table.
The array and methods to get the data of the array can be created in the viewController as well, not necessarily in the AppDelegate, in case you were wondering.
The methods are as follows:
-(NSInteger) numberOfNames
{
return [myArray count];
}
-(NSString*) nameAtIndex: (NSInteger) index
{
return [myArray objectAtIndex:index] ;
}
Hope this helps! :)

UITableview grouped style only showing one value from array?

MY UITableview Group style only showing one value from the array of 4 elements.
in viewdidload i add following array
_displayThemeItems=[[NSArray alloc]initWithObjects:#"Default",#"Night",#"Sepia" ,#"Blue" ,nil];
_displayThemeIcons=[[NSArray alloc]initWithObjects:[UIImage imageNamed:#"day.png"],[UIImage imageNamed:#"night.png"],[UIImage imageNamed:#"sepia.png"], [UIImage imageNamed:#"blue.png"],nil];
and my table delegate methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_displayThemeItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier=#"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// No cell available - create one.
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];}
NSLog(#"rray%#",_displayThemeItems);
cell.textLabel.text = [_displayThemeItems objectAtIndex:indexPath.row];
cell.imageView.image=[_displayThemeIcons objectAtIndex:indexPath.row];
return cell;
}
Your code look fine to me, the only the only reason that I can think amy effect the result you see is how you set up your table view.
Make sure that your table view frame is bug enough to show the 4 items, and make sure you set the tabe view data source.
Add the "}" just before the return such that the code where you set the title and image comes under the "if" statement.

Resources