I need add an ad cell with only image after every five news cells in table view.
If I will add second section for ad cells, an ad cell will be shown after all news cells.
If I will add an ad cell when indexPath.row == 4, my fifth news cell won't appear because of cell.details = news[indexPath.row].
Any suggestions how can I do that? Thanks.
In the method cellForRowAtIndexPath of UITableViewDataSource do next:
if (indexPath.row % 5 == 0) {
// configure ad cell
} else {
// configure usual cell with news[indexPath.row - (indexPath.row / 5)]
}
You need to figure out a system to get the right data for your cells:
0 NEWS
1 NEWS
2 NEWS
3 NEWS
4 NEWS
5 AD <----- "5." => (currentRow % 5 == 0)
6 NEWS <----- "6." => (6 - (currentRow / 5)
You see a system?
You can do something like:
if ((row % 5) == 0) {
//Ad stuff here
} else {
data = tabledata[row - (row/5)];
//news stuff here using data
}
do like this ..
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 4;//add your own number, might be totalNumberOfNewsItems/5
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int reqIndex = indexPath.section*(5) + indexPath.row;
// get data from array like news[reqIndex];
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// return your ad view based on section value
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 44; // change to your required value
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 5 == 0) {
//configure ad cell
} else {
//configure usual cell
}
}
Related
I have an issue while displaying BannerAds for 1st and every 5th row. While displaying data, first row is replaced with banner ads and every 5th row data is replaced with banner ads...How to overcome this. Following is what i have tried.TIA
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger n;
n= [array count];
return n;
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 5 == 0) {
//configure ad cell
for(UIView* view in cell.contentView.subviews) {
if([view isKindOfClass:[GADBannerView class]]) {
[view removeFromSuperview];
}
}
else
{
Title.text=[NSString stringWithFormat:#"%# ",[dict objectForKey:#"Name"]];
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row % 5 == 0)
return 60;
else
return 153;
}
You need to increase the number of cells you return in numberOfRowsInSection and account for the added rows in cellForRowAt
The number of advertisements will be 1 + n/5 (The first row and then every 5th row), so the number of cells in your table will be n + n/5 + 1
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger n;
n= [array count];
return n/5 + n + 1;
}
Now, some of the cells you need to return from cellForRowAt will be ads and you will need to account for this when accessing your data array. The index you need is the row number - the number of advertisement rows that have come before it. This is index/5 + 1 (The first row and every 5 rows).
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 5 == 0) {
AdCell *cell = (AdCell *)[tableView dequeueReusableCellWithIdentifier:"Ad" forIndexPath: indexPath];
...
NSLog(#"Showing an ad at row %ld",indexPath.row);
return cell;
else
{
NSInteger index = indexPath.row - indexPath.row/5 - 1;
NSDictionary *dict = myArray[index];
NormalCell *cell = (NormalCell *)[tableView dequeueReusableCellWithIdentifier:"Normal" forIndexPath: indexPath];
cell.title.text=[NSString stringWithFormat:#"%# ",dict["Name"]];
NSLog(#"Showing a normal row at row %ld (data from element %ld of array)",indexPath.row,index);
return cell;
}
}
I have two UITableViews in the same ViewController, one which uses dynamic height based on UILabel content size and the other where all the cells are static heights. I separated the two TableViews using tags. I tried using this:
self.tableView1.rowHeight = UITableViewAutomaticDimension;
and:
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView.tag == 1) {
return 114.0f;
} else {
if (indexPath.section == 0) {
return 50.0f;
} else if (indexPath.section == 2) {
return 20.0f;
} else {
return 44.0f;
}
}
}
The problem is that the dynamic cells do not change dynamically and the static height cells originally have the right height but when they scroll out of the view they then change to the default height for cells.
Can anyone help please?
When you implement:
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
You need implement both this and
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Normally It´s the same code, add this to your protect:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.tag == 1) {
return 114.0f;
} else {
if (indexPath.section == 0) {
return 50.0f;
} else if (indexPath.section == 2) {
return 20.0f;
} else {
return 44.0f;
}
}
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1) {
return NO;
}
else {
return YES;
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1) {
return NO;
}
else {
return YES;
}
}
I have 2 sections in my tableView. I want my tableViewcells to be moved only in first section(not for second). Currently if i drag my tableCell to second section, It has a crash.
I think you are looking for this method -
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (proposedDestinationIndexPath.section != 0)
{
return sourceIndexPath;
}
return proposedDestinationIndexPath;
}
It will restrict you to move your rows in section 0 only. If you try to move row from section 0 to 1, it'll return the previous indexpath of the cell
I'm looking for the best possible solution for a complex UITableView. What I want : I have an arbitrary number of sections. In this section is just one static cell and then should come any number of dynamic cells.
My Data are stored in some NSMutableArray and i tried somethink like this:
Combine static and prototype content in a table view
But i dont know how to handle it with my kind of problem.
So can somebody give me a hint or a best practice?
UPDATE: 1
http://jsfiddle.net/konstheinrich188/HKkA8/ Fiddle shows how my data looks and what im trying todo
This pic shows how i want to code my tableview...
When you are using the term "static", are you really talking about a "uitableview static cell", or rather "cell with static content"?
If the former; why do you need that?
If the latter; how about testing in each section whether this is the first cell in the section, and then presenting static content? For all other cells, display dynamic content:
if (indexPath.row == 0) {
// First row in section. Display static content
...
} else {
// Display dynamic content
...
}
For what purpose do you need the static cells?
So after a while and some testing and listen to your ideas and technicals i solved my problem!
Here is a little code :
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [mappedSprints count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
UISprint*s = [mappedSprints objectAtIndex:section];
return s._name;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
UISprint* s = [mappedSprints objectAtIndex:section];
return [s.internalUserStorey count] + [s.externalUserStorey count] + 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
return 130;
}
return 80;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:#"Cell%d%d", indexPath.row, indexPath.section]];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[NSString stringWithFormat:#"Cell%d%d", indexPath.row, indexPath.section]];
}
UISprint*s = [mappedSprints objectAtIndex:indexPath.section];
if (indexPath.row == 0) {
//Here is my first cell
//cell.textLabel.text =s._name;
}
else if(indexPath.row >= 0 && indexPath.row<=[s.internalUserStorey count]){
//here are the cells for SubItem
}
else if(indexPath.row >= [s.internalUserStorey count]){
//here are the cells for SubItem 2
}
return cell;
So thanks to all !!
Best Konstantin
You can take one NSMuatableArray and add references on that i.e.
NSMuatableArray *arr=[NSMuatableArray alloc]init];
//section no 1
[arr addObject:#"2"];
//section no 2
[arr addObject:#"1"];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
switch(arr objectAtIndex[indexPath.row])
{
}
}
you can use this way by using references you want set cells.
I am new at iOS development.
I want to check if my table is empty. If it is, I want to :
Increase height of the first row and display "No new messages!"
OR
Get rid of the table and just display "No new messages" in the center of the page.
How would I do that?
(Let's assume you have an array from which you want to populate the table view. This is a pretty standard way for populating table views. Let's call this theoretical array dataArr.)
In your data source:
- (NSUInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSUInteger)section
{
if ([dataArr count] == 0) {
// empty table
return 1;
}
return [dataArr count];
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)ip
{
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:#"someCellID"];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"someCellID"] autorelease];
if ([dataArr count] == 0) {
// empty table
cell.textLabel.text = #"No new messages";
} else {
// configure as normally
}
return cell;
}
In your delegate:
- (CGFloat)tableView:(UITableView *)tv heightForRowAtIndexPath:(NSIndexPath *)ip
{
if ([dataArr count] == 0) {
// empty table
return 88.0f; // 2 times the normal height
}
// else return the normal height:
return 44.0f;
}
I suppose you have an array of messages you are attempting to display
You can define custom height for cells with the function
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (messages.count == 0)
return 80;
else
return 44;
}
and then, when you are creating the cells: (make sure the "no new messages" cell has a different cell identifier than the regular cells, so that your cell re-use won't mess things up)
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (messages.count == 0) {
// create the "No New Messages" cell
}
else {
// create regular cells
}
}
This should help:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([tableView numberOfRowsInSection:1] == 0) {
return 200;//some other height
}else{
return 44;
}
}
Basically you want to check against your data source to see if you have no messages in the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath and - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
For example:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([data count] == 0) return 100;
else return 44;
}