I have a UITableView with 16-20 cells inside with dynamic cell size. When a cell expands it self it should also move itself to the top of the screen. I did that using "UITableView setContentOffset" method. It works well except for the last cell in table, it's not able to move itself to the top.
I tried altering the frame & content size of UITableView but none of those were working for me!
Any Idea?
[UPDATE]
Here is a part of code: (it's inside the UITableViewCell, so self is pointing to current cell)
HomeViewController *tempViewController = (HomeViewController *) delegate;
UIView *commentField;
/*Skipping lines of codes manipulating commentField */
//Adding a subview to current cell which needs more space
[self addSubview:commentField];
//Expanding cellSize to EXPANDED_CELL_HEIGHT
//ViewController has access to cell size property and using that to determine each cell size.
[self setCellSize:(EXPANDED_CELL_HEIGHT)];
//Reloading UITableView to reflect the cell size change with animation
[[tempViewController tableView] beginUpdates];
[[tempViewController tableView] endUpdates];
[[tempViewController tableView] setContentOffset:CGPointMake(0, self.frame.origin.y) animated:YES];
and in my view controller (as I said earlier) I'm getting cellSize form cell itself
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [(BaseTableViewCell *)[cellContainer objectAtIndex:indexPath.row] cellSize];
}
You can change the height of the cell using the tableview delegate method heightForRowAtIndexPath: When indexPath.row equals your last row, return the height you would like.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == i)//i being whatever row index you want to change
{
return 60.0;//or float size you want
}
else
{
return 30.0;
}
}
Or you can just modify the bounds of the cell inside willDisplayCell:. If your using a custom tableview cell, just shrink the subviews to whatever frame you'd like and make the cell background clear etc.
Related
In my iPhone application I have four types of cells. Every cell has it's own height. I'd like to set the height of the row for each table view cell but it crashes in this method:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSLog(#"%#", cell);
if([cell.reuseIdentifier isEqualToString:PastEventWICellIdentifier]){
return 56;
}
if([cell.reuseIdentifier isEqualToString:PastEventWOICellIdentifier]){
return 56;
}
if([cell.reuseIdentifier isEqualToString:EventWICellIdentifier]){
return 112;
}
if([cell.reuseIdentifier isEqualToString:EventWOICellIdentifier]){
return 112;
}
return 56;
}
How can I resolve this?
You cannot get the cells using cellForRowAtIndexPath inside the method heightForRowAtIndexPath, because the cells are not there yet. They will be created after their heights are set.
You may set the heights of the cells based on their location using indexPath.row.
You cannot use method cellForRowAtIndexPath, this method is called before cellForRowAtIndexPath so the cells don't exists. You should have a list of Height already calculated when heightForRowAtIndexPath is called. Remember to not load all list in tableview because this method (heightForRowAtIndexPath) takes longer to load tableview...
Hello I am currently using Simon Lee's wonderful tutorial to expand my cells. Everything is working fine.
My cells are 100px, and when expanded the cell becomes 144px high. In the added 44px I have placed a toolbar with bar buttons. I've gotten the buttons to work but there is one problem.
When the cell is expanded I can tap any of the 100px and the cell closes, however when the cell is closed , tapping on the lower 44px of the cell causes the bar buttons to fulfill their actions. I'm assuming that it's still enabled if when hidden from site.
I have disabled user interaction in storyboard but can not get it to turn on when cell is selected and vice versa! If anyone could point me in the right direction that would work!
Simon said something about doing the following, but I'm not quite sure on where to exactly implement it! I've tried it everywhere!
for(NewsCell *cell in [self.tableView visibleCells]) {
BOOL cellIsSelected = [selectedIndexes objectForKey:indexPath];
[cell.detailToolbar setUserInteractionEnabled:cellIsSelected];
}
And here's some of my code:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// If our cell is selected, return double height
if([self cellIsSelected:indexPath]) {
return 144.0;
}
// Cell isn't selected so return single height
return 100.0;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Deselect
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
self.tableView.clipsToBounds = YES;
// Store cell 'selected' state keyed on indexPath
NSNumber *selectedIndex = [NSNumber numberWithBool:isSelected];
[selectedIndexes setObject:selectedIndex forKey:indexPath];
// This is where magic happens...
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
The clipsToBounds for the tableView in the didSelectRowAtIndexPath looks a little strange to me
self.tableView.clipsToBounds = YES;
Did you set the clipoToBounds to YES for your cells?
I figured it out on my own. It turns out that all I had to do was set the user interaction in my cell to off. and switch it on for the selected cell.
for(NewsCell *cell in [self.tableView visibleCells]) {
BOOL cellIsSelected = isSelected;
[cell.detailToolbar setUserInteractionEnabled:cellIsSelected];
}
There are 1 table on uiview and I want to change the cell height when button pressed other cell's height remain same
Pass the button press event to the view controller through delegate methods and reload the table view as follows.
[self.tableView reloadData];
In view controller (ie., datasource for the table view), implement heightForRowAtIndexPath method and return the height as required.
You can change the cell height in the delegate method
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.row == clickedRow)
return newHeitht;
return cellHeight;
}
you can set some condition in button click and reload the tableview using [tableView reloadData]. this function will be called. return a new height for the particular cell.
-(void)buttonClick {
[self.tableview reloadData];
selectedRow = //do something here
}
and in your UITableview Datasource
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {
if(indexPath.row == selectedRow)
return selectedRowHeight;
else
return defaultHeight;
}
1) Create a custom UITableViewCell class.
2) Populate you cell however you see fit. I use a 'hydrateWithArray' type function myself.
3) Once the data has been populated, resize and reposition elements using 'sizeToFit' functions to force labels to conform to the size of whatever you put into them. protip: by setting the frame of the label first, and setting the numer of lines to 0... when you fill the text and sizetofit, it will stretch the label vertically only and force the width to stay the same.
4) Create a seperate function (mine is called calculatedHeight) that returns a float and returns the height that you would like the cell to be in the table (based on the repositioned objects from step 3).
- (float)calculatedHeight {
return textLabel.frame.origin.ytextLabel.frame.size.height5;
}
5) In your UITableView class, you'll need to import your tableViewCell class and create a dummy cell object. You're going to use this class to calculate how tall each cell needs to be. Then in the heightOfRowAtIndex method....
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
float height;
if ( !dummyCell ) dummyCell = [[CustomCell alloc] initWithFrame:CGRectMake(0,0,0,0) reuseIdentifier:#"myCell"];
[dummyCell hydrateWithTweet:[tableArray objectAtIndex:indexPath.row]];
height = [dummyCell calculatedHeight];
if ( height == 0 ) height = 50;
return height;
}
This is a pretty simple example so you may need to go crazy with the error checking in your particular use, but this should at least point you in the right direction. Enjoy!
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (isSearching && indexPath.row == selectedIndex) {
return 110;
}
else {
return rowHeight;
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:toReloadRows withRowAnimation: UITableViewRowAnimationNone];
[self.tableView endUpdates];
then
[self.tableView beginUpdates];
[self.tableView endUpdates];
How can I eliminate views created upon selecting a cell in UITableView when the cell is no longer selected or other cell is on selection.
Suppose I have the code below for didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CGSize cellSize = [tableView cellForRowAtIndexPath:indexPath].frame.size;
UIView *selectionView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, (int)cellSize.width, (int)(cellSize.height + 100))];
selectionView.layer.borderWidth = 2;
[[tableView cellForRowAtIndexPath:indexPath]addSubview:selectionView];
}
Now, I want to remove that created selectionView when I focus on another cell and create it again to the cell which I am focusing.. The problem is that when I select a cell for the first time, it works perfectly but when I select another cell, the selectionView created from the previous cell still does not disappear and it duplicates the view already. How am I suppose to solve this? Need suggestion.. :( thanks..
You need to add tag for the selectionView as follows
selectionView.tag = 100;
Also , you need to have the reference of the last selected indexPath by declaring a NSIndexPath class member and retaining it.
So while selecting a new cell, get the cell with last selected indexpath and remove the view from the cell as follows
UITableViewCell *lastCell = [tableView cellForRowAtIndexPath:lastSelIndexPath];
UIView *view = [lastCell viewWithTag:100];
[view removeFromSuperview];
You really need to look into subclassing UITableViewCell if you want a custom selection UI. Then override [UITableViewCell setSelected:animated:] (or [UITableViewCell setHighlighted:animated:]) to perform your customisations.
When i select a cell in my tableview, the cell was pushed to the left by the accessoryTypeCheckMark.
my custom cell was programmatically inserted into a tableview
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:
indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryNone) {
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
selectedCell.accessoryType = UITableViewCellAccessoryNone;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I was tearing my hair out over this too but luckily I was able to turn on the left side autoresizing constraint for my subview in Interface Builder, to keep it aligned to the left of the cell. The width and right side constraints are disabled. In my case, this keeps a 100 pixel wide UIView pinned to the left of the cell regardless of whether UITableViewCellAccessoryCheckmark is shown, and also keeps its width constant even if the table cell width changes.
Depending on the contents of your cell (more specifically, depending on how far to the right the text extends), the contents will be re drawn to make room for the check mark to appear.
If you don't want the text to move, you'll need to draw cell contents yourself using a custom cell subclass.