i am a new programmer of Iphone App..... i wants three cells in table (which are different height)
i write the code for this task..and output is satisfactory...... but i don't know.. this is right method or not.....
thanks in advance..... :)
CGRect frame=CGRectMake(5, 43, 311, 363);
UITableView *table=[[UITableView alloc]initWithFrame:frame style:UITableViewStylePlain];
table.dataSource=self;
table.delegate=self;
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath
{
static int counter=1;
if(counter==1)
{
counter=counter +1;
return 163;
}
else if(counter ==2)
{
counter=counter +1;
return 80;
}
else
{
counter=counter +1;
return 60;
}
if(counter==4)
{
counter=1;
}
}
No, this isn't right. Use indexPath.row instead of your counter variable. This will be the row number your delegate is being asked about. When scrolling upwards, for example, you may not get the expected results with your current code.
Don't use
static int counter=1;
Get the row from NSIndexPath.
int row = indexPath.row;
your static int counter is not a global variable, so you code can't work.
It would work, if you make an ivar from it but that is not the correct way to solve that.
The indexPath variable provided by the heightForRowAtIndexPath: delegate method holds the index of the actual item. Just call indexPath.row (this is the actual counter) in your code instead of your counter.
From your code I guess you have a rotation of 3 rows heights, so the best way is to use int row = indexPath.row % 3; this will give you a cycling 0,1,2 as value to test instead of your counter
Related
In a plain UITableView with custom UIView's as section headers, is there a way to calculate:
When one of the Section is on the top, the distance between that section and the next one that would come?
I am expecting to calculate this here:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
You can find the number of rows in that section by calling the tableView:numberOfRowsInSection: method from the UITableViewDataSourceDelegate protocol. You can get the height for each row in the section with the tableView:heightForRowAtIndexPath: method from the UITableViewDelegate protocol. Add up the height for all the rows and you have the distance you want.
Your code would look something like this, assuming you have a reference to the tableview and the section.
float totalHeight = 0;
for (int i = 0; i < [tableViewDataSourceDelegate
tableView:tableView
numberOfRowsInSection:section]; i ++) {
totalHeight += [tableViewDelegate
tableView:tableView
heightForRowAtIndexPath:[NSIndexPath
indexPathForRow:i
inSection:section]];
}
Haven't had a chance to test this code, but it Should Work[tm].
Edit
This will only work if the header is at the top.
(assuming all rows are same height)
NSIndexPath *topCellIndexPath = [tableView indexPathsForVisibleRows][0];
UITableViewCell *topCell = [tableView cellForRowAtIndexPath: topCellIndexPath];
CGFloat distanceToNextSection = [tableView convertRect: [topCell frame] fromView: topCell.superview].origin.y - tableView.contentOffset.y + ([self tableView: tableView numberOfRowsInSection: topCellIndexPath.section] - topCellIndexPath.row)*tableView.rowHeight
I was able to solve this by doing the following:
Before creating an section header, check if you have the section header for a given section. If you do return it from the NSMutableArray. If not keep going.
When you create the section header, keep a reference to it in a NSMutableArray.
When you scroll in:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
Do the following:
// Get the toppest section
NSUInteger sectionNumber = [[self.tableView indexPathForCell:[[self.tableView visibleCells] objectAtIndex: 0]] section];
// Get a reference to it
SFBasicSectionHeader *topHeader = [arrayOfWeakHeaders objectAtIndex:sectionNumber];
SFBasicSectionHeader *bellowHeader;
// Check if it's Ok to get the bellow header
if (sectionNumber+1<[arrayOfWeakHeaders count] && [arrayOfWeakHeaders objectAtIndex:sectionNumber +1])
{
bellowHeader = [arrayOfWeakHeaders objectAtIndex:sectionNumber+1];
}
The difference between both will be:
CGFloat differenceBetweenTopAndBellowSection = bellowHeader.frame.origin.y - topHeader.frame.size.height - self.tableView.contentOffset.y;
Done.
I am using TTTableViewController class. I have added the UIView of height 100 to the Table cell initially. The height of UIView changes dynamically and I have to change the height of cell also. But height of the cell doesnt chnages. please remember I am ?Using Three 20. Thanks in advance for valuable response.
Have you Enabled this while creating row Dynamically??
BOOL variableHeightRows = YES
You can refer this link, hope it may help you. :))
Or try this :-
-(CGFloat)tableView :(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// return (the value for the row)
}
but for this you must implement its Delegate i.e. UITableViewDataSource.
use the below delegate method to adjust table row height.
-(CGFloat)tableView :(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 50; //the required table row height
}
For TTTableViewCell
do it in didLoad or init method
self.variableHeightRows = YES;
and use the below function.
+ (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object;
{
return 80; //value can be changed
}
This is related to another question of mine which wasn't answered in a helpful way (message when a UITableView is empty).
I'm trying to show an UIImage graphic that says You haven't saved any bookmarks over an UITableView when it's empty. I have NSNotification set-up so that when bookmarks are added or deleted, a message is sent so that the UITableView can be updated.
I've been trying to do it with this code. Why won't this work?
- (void)bookmarksChanged:(NSNotification*)notification
{
[self.tableView reloadData];
UIImageView* emptyBookmarks = [[UIImageView alloc] initWithFrame:CGRectMake(75, 100, 160, 57)];
emptyBookmarks.alpha = 1;
emptyBookmarks.image = [UIImage imageNamed:#"emptyBookmark.png"];
[self.view addSubview:emptyBookmarks];
[emptyBookmarks release];
if ([self.dataModel bookmarksCount] == 0)
{
emptyBookmarks.alpha = 1;
}
else
{
emptyBookmarks.alpha = 0;
}
}
I'm probably approaching this the wrong way... But if salvageable, what am I doing wrong?
When I initially have an empty bookmarks tableview, there's no image displayed. After I add a bookmark and then delete it, the image shows. Grrh.
Another way (and IMO the correct way) to do this is to manipulate the backgroundView property on the UITableView.
While making a single cell with a custom image cell would certainly works, I think it overly complicates the logic of your UITableViewController's data source. It feels like a kludge.
According to UITableView documentation:
A table view’s background view is automatically resized to match the
size of the table view. This view is placed as a subview of the table
view behind all cells , header views, and footer views.
Assigning an opaque view to this property obscures the background color
set on the table view itself.
While you probably don't want to just set it to your UIImageView, it is very easy to make a UIView that contains the UIImageView that you want.
Well first off if you were going to do it that way, you would need to reload the tableView after updating the image or model etc. and not before.
But you are probably making things more complicated than they need to be!
Why not just check to see if the data for section 0 and indexPath.row 0 are empty and if so in cellForRowAtIndexPath display a text message accordingly.
// First make sure there is always one row returned even if the dataModel is empty.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger numRows = 0;
if ([self.dataModel lastObject]) {
// Return the number of rows in the section.
numRows = [self.dataModel count]; // etc.
}
if (numRows < 1) numRows = 1;
return numRows;
}
// Then display the data if there is some, otherwise a message if empty.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if ([self.dataModel lastObject]) {
// setup the cell the normal way here.
} else { // the datasource is empty - print a message
cell.textLabel.text = nil;
cell.detailTextLabel.text = NSLocalizedString(#"You haven't saved any bookmarks", #"");
cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.7];
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Are you sure [self.dataModel bookmarksCount] is equal to 0 ?
While I agree that you are probably going about this the wrong way,
your image is allocated and added in your bookmark changed, your notification does not trigger when there are no bookmarks initially. Hence you don't see the image. Call the bookmar changed when your table view inits or appears.
Probably the best way to achieve this is to perform a check in your numberOfRowsInSection method to return 1 if your data source is empty. Then in cellForRowAtIndexPath check if your data source is empty and if it is, create a custom cell that contains whatever you want. In heightForRowAtIndexPath you need to return your custom cell height if your datasource is empty, but only if you want the cell larger than the default. At least that is how I would approach it.
when bookmarks count is nil add one to your row method:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
int c;
c = bookmarks.count;
if(c == 0){
c = 1;
}
return c;
}
and then the same check again in your cellforrowatindexpath.
Another thing to be aware of in this situation is that if you're using core data and you're datasource is feeding off an entity, you will want to make sure your model matches. You can get some weird side-effect behavior in certain situations. This is especially true if you allow editing and core data has an empty model but you're tableview is still showing a cell.
how can i get UITableView row count in didSelectRowatIndexPath.can any one tell me a good way to get it
If you use something like this:
NSLog(#"%i", [indexPath row]);
and you should get the number of the row selected returned in the console. Alternatively you could pass [indexPath row] into a variable and use it inside a conditional statement to perform a different action depending on row selected like this:
int rowSelected = [indexPath row];
if(row == 0)
{
//do something
}
else if(row == 1)
{
//do something else
}
Hope this helps
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [array count];----->this is the row count You have to use in didselect row method
}
a=indexPath.row;
the a variable has the value you want
You need to track the number of records passed in numberOfRowsInSection for all sections. If its varying you can keep a variable that stores the number.
Is there a way to give each cell in a grouped tableview an incremental number as its tag?
E.g:
Group 1
cell 1 (tag = 1)
cell 2 (tag = 2)
cell 3 (tag = 3)
Group 2
cell 1 (tag = 4)
cell 2 (tag = 5)
Group 3
cell 1 (tag = 6)
etc...
Any help is greatly appreciated!
This is not possible without querying the datasource for the count of cells that are in previous groups. And you probably don't want to do that. Doesn't make sense anyway, because you have to implement proper reuse to get good performance, so tags appear and disappear any time.
So the real question is, why do you want to do this? There is probably a way to achieve the same without adding tags.
But if you really want to:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger count = 1;
for (NSInteger i = 0; i < indexPath.section; i++) {
count += [[tableView dataSource] tableView:tableView numberOfRowsInSection:i];
}
count += indexPath.row;
// dequeue, create and configure...
cell.tag = count;
return cell;
}
Create a variable
Create a loop which will iterate through all cells
At the end of each loop add 1 to the variable