I'm trying to figure out how to optimize performance and improve code quality.
I have the following layout:
OuterTableView
Outer Cell
UILabel (title label)
InnerTableView
Inner Cell (item cell)
Inner Cell (item cell)
...
The purpose of this layout is expandable outer table. In collapse state only UILabel (only title label) is visible. When user clicks on outer cell, cell is expanded and reveals inner cells.
In outer table controller I have 3 functions (simplified):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.tableView) {
// ServiceGroupCell - outer cell
ServiceGroupCell *serviceCell = [tableView dequeueReusableCellWithIdentifier:#"service_group_cell"];
[self configureCell:serviceCell forIndexPath:indexPath];
return serviceCell;
}
return nil;
}
- (void) configureCell:(ServiceGroupCell *) cell forIndexPath:(NSIndexPath *) indexPath {
// styling for outer cell and passing data for inner cells
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
ServiceGroupCell *serviceGroupCell = [tableView dequeueReusableCellWithIdentifier:#"service_group_cell"];
[self configureCell:serviceGroupCell forIndexPath:indexPath];
[serviceGroupCell layoutSubviews];
CGFloat height = [serviceGroupCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
return height;
}
Inner table controller
- (void)layoutSubviews {
[self.cellTableView layoutSubviews];
// set height constraint for inner table view
self.heightLayoutConstraint.constant = self.cellTableView.contentSize.height;
}
I have questions:
1) As you can see for each cell of outer table configureCell is invoked twice. Are there any ways to cache or just call it once?
2) systemLayoutSizeFittingSize returns 0. Are there any ideas why?
2) systemLayoutSizeFittingSize returns 0. Are there any ideas why?
Your constraints are probably missing. Make sure you specify constraints for the width and height of the cell in the .xib file.
Cells inner other cells is a bad idea, i think. You can make some sections, and using method didSelectRowAtIndexPath for when user tap on cell in section add cells to this section. Or use scrollview with custom nsview in which put tableview. Thats just work around.
Are there any ways to cache or just call it once? - try willDisplayCell method.
Related
I have a section with dynamic multiple rows and I need to separate all the section with the background as shown in the image below.
Specifically those border lines for all the section. Pease let me know how can I make it possible.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{
return ProductArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *arr = [ProductArray objectAtIndex:section];
return arr.count;
}
Please refer to this
.
I tried adding header and footer, But I am not understanding how to add that rectangle box image for the entire section.
Put View in your cell after make outlet of that view. And use to cellForRowAtIndexPath this method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TableViewCell" forIndexPath:indexPath];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.viewBackGround.backgroundColor = [UIColor redColor];
return cell;
}
For above requirement, I would like to suggest you the below approach.
create only one section with multiple rows.
Each row of UITableView will have UITableViewCell
Inside UITableViewCell create content view for which we are gonna add the border
Each row of UITableViewCell will have another UITableView(inside content view) whose methods are handled by UITableViewCell cells
Change UITableView (inside) height based on number of rows.
provide height of UITableViewCell based on the number of rows + orderID Header.
We can get a cell from:
UITableViewCell * cell = [self tableView:tableVie cellForRowAtIndexPath:indexPath]
but it will calling the method cellForRowAtIndexPath:
if I know the cell's tag or indexPath , it's there a way to get the specified cell without to calling cellForRowAtIndexPath:?
Add some reason why I can't call cellForRowAtIndexPath:indexPath
I want to get the cell in the method cellForHeightAtIndexPath to reset the height of each cell. :
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
CommentsListResponseDataModel * model = self.liveCommentData[indexPath.row -1];
if (model.viewHeight > 0) {
return model.viewHeight;
} else {
if (model.parentComment) {
CommentParentCell * cc = (CommentParentCell *)cell;
return cc.viewHeight;
} else {
CommentSingleCell * cc = (CommentSingleCell *)cell;
return cc.viewHeight;
}
}
}
}
But this will become a dead loop because it all cellForRowAtIndexPath:indexPath and cellForRowAtIndexPath:indexPath will recall cellForHeightAtIndexPath:indexPath
As of my understanding, you are trying to get the cell object by calling UITableView datasource method. But when you try to do like that then it will be infinite loop call and you will never get the cell object. So in order to get cell object from UITableView, do the following steps.
Declare your UITableView as global to the your ViewController, something like UITableView *_tableView; or #IBOutlet weak UITableView *_tableView;
Then try to call the
//specify the item indexpath
NSIndexPath *_indexPath = [NSIndexPath indexPathForItem:3 inSection:1];
//now try to access cell object by passing cell indexPath
UITableViewCell *_cell = [_tableView cellForRowAtIndexPath:_indexPath];
It seems you want something unrelated to your original question - you want your table view cells to size automatically, depending on content.
What you need to do is:
1. add constraints to your cell - make sure it doesn't have a height constraint, but its content must have Top and Bottom constraints.
2. remove heightForRowAtIndexPath as it will not be necessary
3. set your table view row height to automatic
tableView.rowHeight = UITableViewAutomaticDimension
Now just setup your cell - resize its content to desired height and table cell will automatically be resized
I've 3-5 dataSource and in ViewDidLoad() I've mentioned the property for dynamic cell height:-
[self.tableView setEstimatedRowHeight:40.0];
[self.tableView setRowHeight:UITableViewAutomaticDimension];
but the tableview don't update accordingly.. first two-three cell shows contents in good way but as soon as I scroll the tableview, cell gets compressed and then cell shows half of the content.
UPDATED
screen of customCell is
tableViewCell
andConstraints Are:tableViewCellConstraint
I have a UIView in cell and label and a uiimageview inside the view
More Update::
I think its coz i'm also using an empty cell to have a space between two cell and in the delegate method for i doing this
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 20.0;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row %2 == 0) {
return 15;
}
return UITableViewAutomaticDimension;
}
I have a standard tableview of .Subtitle style. However, I would like to show the detailed text only when the cell is swiped. I would like to increase the height of the swiped cell (and only the swiped cell) to display the detailed text. I have not tried creating 2 cell prototypes and swapping the cell on the swipe and I am not experienced enough to implement it. I could implement the optional function heightForRowAtIndexPath but that would change every cell unconditionally.
I would appreciate any ideas on how to do this.
In tableViewheightForRowAtIndexPath method, you could change specific cell height, and keep other cells in the same height.
you can check the below sample code
NSIndexPath *selectedCellIndexPath;
//
- (void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedCellIndexPath = indexPath;
// Forces the table view to callheightForRowAtIndexPath
[tableView reloadRowsAtIndexPaths:[NSArrayarrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationNone];
}
- (CGFloat)tableView:(UITableView *)tableViewheightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Note: Some operations like calling [tableViewcellForRowAtIndexPath:indexPath]
// will call heightForRow and thus create astack overflow
if(selectedCellIndexPath != nil
&& [selectedCellIndexPathcompare:indexPath] == NSOrderedSame)
return 64;
return 32;
}
I have a table view and I want to include margins so that the table's content has some breathing room on the left and right, and also between cells.
I managed to do a table view like:
My Storyboard design is like:
What I did was I added a UITableView to the main view and gave a margin of 10. I added constraints as shown in figure. Changed the Seperator style to None.
Then I added two UITableViewCells.
For Holding the data with custom row height 70.0
Row with same background of parentView with custom row height of 10.0
And implemented the methods like below:
// Row count (Twice as needed, for showing the insect)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 15*2;
}
// Returns cell based on indexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
// Decides whether content or inset
if (indexPath.row%2)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"ReuseInset"];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:#"ReuseMe"];
cell.textLabel.text = #"MMP";
}
return cell;
}
// Returns custom row height based on indexpath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ if (indexPath.row%2)
{
return 10.0;
}
return 70.0;
}