UITableViewCell's frame only updated after scrolling - ios

I change the frame of cells (add margins to the left and to the right) according to the code. The problem is cells update their frames only after they disappear and appear again via scrolling. I used table view's - reloadData as well, but it did't help. How do I force cells to be redrawn without scrolling?
- (UITableViewCell *) tableView: (UITableView *) tableView
cellForRowAtIndexPath: (NSIndexPath *) indexPath {
PersonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: #"TableViewCellID"
forIndexPath: indexPath];
cell.frame = CGRectMake(20, cell.frame.origin.y, cell.frame.size.width-2*20, cell.frame.size.height);
/* tried any of those
[cell setNeedsDisplay];
[cell setNeedsLayout];
[cell layoutIfNeeded];
*/
return cell;
}

I'd recommend using .xibs for this. Much easier.
As far as I know, you are not able to change the frame of a cell in that manner. The cell's height is determined by heightForRowAtIndexPath, and the width is set to the width of the tableView.
You may be able to do it in some manner the way you are attempting, but the cleanest way I know is the following.
If you want there to be a margin around the cell, you can:
Create a nib for a UITableViewCell with a UIView containing all your views, and place a border using constraints.
Embed all your content inside a UIView (lets call this borderedContentView) and place this as the immediate subview of contentView
Place constraints relating borderedContentView to the contentView, with the leading, trailing, top and bottom constraints set to the values that create the border width you desire.
If your tableView has a backgroundColor, you'll have to set the contentView's backgroundColor to the same color as the tableView's backgroundColor so as to create the illusion of a margin. Do this in the tableView's delegate method willDisplayCell: or in a subclass of UITableViewCell awakeFromNib or other related method.
Bask in the glory of your margined cells.
You can also do this programmatically if you prefer not to use interface builder, but it is very easy to do in IB.
Hope this helps.

The solution to the problem is to override setFrame method of UITableViewCell. This way it perfectly works.

Related

seprator is not visible in uitable view for dynamic height?

I am designing an app in which i have used a table view.This table view uses a custom cell.I have given proportinal height to the table view.T
tableview height constraints:
equal height to mainview
multiplier:189:568
Cell properties
cell height:77
Image constraints:
Label constraints
TextViewContsraints
bottom right label constraints
Code to make the row height dynamic
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:
(NSIndexPath *)indexPath
{
float percentage = (77.0 / 568.0);
float height = self.view.frame.size.height * percentage;
return (height>77.0)?height:77.0;
}
Issue screen
Is the UITableViewCell in IB associated with a UITableViewCell subclass that overrides drawRect:? If so, make sure you are calling the super implementation, as that's what draws the line at the bottom. If you are overriding layoutSubviews make sure no views are obscuring the bottom of the cell.
In my case, i forgot to call [super layoutSubviews] after overriding the layoutSubviews method. Took me hoursto find the problem.
Hope this will help you.
Increase custom cell size to 80-88 may be it solve your problem

UITableViewCell change subviews positions after being selected

I created a dynamic cell using AutoLayout, put code in (void)updateConstraints cell's subview method, set BOOL value so custom AutoLayout code runs only once, and in View Controller call
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
just before returning cell. Everything seems to works fine but I'm experiencing weird issue, when I select cell all its subviews (or itself?) change position.
cell pointed with this beautiful arrow shows it ;]
I experienced the same bug and tinkered for about a day to fix this ... to get to the bottom of the issue I set different background colors on the cell & the content view. Right after first showing the table view everything seemed to work, but after selecting the cell the contentView would jump around - sometimes when selecting, sometimes when deselecting (which I do immediately in tableView:didSelectRowAtIndexPath:), and the cell's background became visible. So I figured the cell somehow didn't reestablish the correct contentView dimensions.
Finally it turned out that at least in iOS 8 you need to set the appropriate autoresizingMasks for the cell as well as the contentView, and then make the layout system translate them into constraints by setting translatesAutoresizingMaskIntoConstraints to YES. At the same time this flag needs to be NO on all subviews of your contentView.
So here's my initialisation for custom cells:
- (void)awakeFromNib {
// enable auto-resizing contentView
[self setTranslatesAutoresizingMaskIntoConstraints:YES];
[self.contentView setTranslatesAutoresizingMaskIntoConstraints:YES];
self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
// remove autoresizing constraints from subviews
for (UIView *view in [self.contentView subviews]) {
view.translatesAutoresizingMaskIntoConstraints = NO;
}
}
Works like a charm for me. For the record, I'm using the UITableViewCell auto-sizing which was introduced in iOS 8, like this:
// enable automatic row heights in your UITableViewController subclass
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 80.0; // set to whatever your "average" cell height is
I found solution to this issue,I used instructions under this link dynamic-cell-layouts-variable-row-heights to implement dynamic table view cells: [Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
[1]: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights. Author suggests to use this two methods to update constrains when using updateConstraints method inside cell's subview.
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
but what I found in my case is there was some issue that not all cells was updated as they should. Solution is to call [cell updateConstraints] in (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath and not wait until system will update constrains.

TextView inside a table cell fo tableview not displaying correctly

I am now followind maybe a bit obsolete tutorial from iOS Apprentice regarding geolocation.
Anyway the job to be done seems extremly easy:
placing text view inside table view cell. On storyboard everything looks greate but when I run it, it looks like presented on picture below (the textview covers the below category table cell view item):
I have following settings:
What is the best way to keep textview inside the table view cell and text just wraps, and overllay-y (so it is called in CSS - I am newbie to iOS) will be added to textview?
I agree with #railwayparade you should use
cell.textLabel.numberOfLines = 0;
Use heightForRowAtIndexPath to calculate the size the cell needs to be
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// replace "THE_TEXT" with the text you are displaying and "TEXT_LABEL_FONT" with the font you're using in the cell
CGSize size = ["THE_TEXT" sizeWithFont:"TEXT_LABEL_FONT" constrainedToSize:CGSizeMake(self.table.bounds.size.width, HUGE_VALF) lineBreakMode:NSLineBreakByWordWrapping];
return size.height;
}
You might want to subclass UITableViewCell and override layoutSubviews to set the textLabel to the exact right size, and add padding as you see fit
-(void)layoutSubviews // in your UITableViewCell subclass
{
[super layoutSubviews];
self.textLabel.frame = CGRectMake(0.0f,0.0f,self.contentView.bounds.size.width,self.contentView.bounds.size.height);
}
Don't forget if you do add padding on the width in layout subviews, you'll have to change the constrained width in heightForRowAtIndexPath

UITableCell clipToBounds property odd behavior

I have a custom UITableCell that has labels and a UIView.
Lets say the tablecell is set at a height of 50px and 10 labels are placed with 10px seperation. With cell.clipToBounds = YES, we only see 5 of the labels which is nice and expected.
The custom UIView on this custom table cell is say 200px in height. I ASSUMED the UIView would get clipped as the labels did because the UIView is added as a subview to the cell itself which clips everything else just fine but the UIVIew doesnt get clipped at all. The entire UIView (200px height) is shown.
pseudo code:
cellForRowAtIndexPath... ... {
...
...
CustomCell * cell = ... ...
cell.clipToBounds = YES;
cell.customView.hidden = NO;
[self.view addSubView:cell.customView];
[self.view bringSubviewToFront:cell.customView];
}
In storyboard i literally create a custom cell and add 10 labels as mentioned above and drag and drop a UIView in the cell with a large height.
So why don't views added to "content view" of UITableViewCell get clipped?
also set cell viewContent clipsToBound
cell.contentview.clipToBounds = YES;
and also check if the cells are overlapping, then make sure you are passing the right height in heightForRowAtIndexPath method of tableview.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 50;
}

How to remove UITableView's NSAutoresizingMaskLayoutLayoutConstraint?

I designed a custom UITableViewCell by adding some subviews in the cell's contentView, I also added some auto layout constraints between the contentView and the subviews.
But when I debug the app, Xcode tells me that there is a constraint conflict. In the list of constraint, there is one NSAutoresizingMaskLayoutLayoutConstraint that limits the cell height to be 43, so Xcode break the constraint of my subview height and 'compress' it.
I have tried:
In Interface builder, uncheck the "autoreize subviews" checkbox. Doesn't work.
In code, cell.contentView.translatesAutoResizingMaskIntoConstraints = NO. This causes the app to crash with an exception: "Auto Layout still required after executing -layoutSubviews". I have tried every proposed solution in this question: "Auto Layout still required after executing -layoutSubviews" with UITableViewCell subclass None of them work for me.
So I guess I can only let the cell do its autoresizing thing, and remove the auto resizing constraint in code. How should I do it without breaking things?
EDIT:
Or, from another perspective, how I can make the tableViewCell height flexible (changes with subview height and constraints)? In IB, I have to set its height, right?
You DON'T need to set cell.contentView.translatesAutoResizingMaskIntoConstraints = NO
In order to get the flexible height in UITableViewCells in autolayout you need to manually compute for the height in - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Yes this tedious, but there is no other way. To calculate the height automatically you need to fulfill two conditions in your UITableViewCell:
You must make sure all your subviews have
translatesAutoResizingMaskIntoConstraints=NO
Your cell subview's constraints must be pushing against the top and bottom edges of the UITableViewCell.
Then in your - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath, You need to recreate that cell for the specific indexPath and compute the height manually for that cell.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath
*)indexPath
{
//Configure cell subviews and constraints
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
[self configureCell:cell forIndexPath:indexPath];
//Trigger a layout pass on the cell so that it will resolve all the constraints.
[cell setNeedsLayout];
[cell layoutIfNeeded];
//Compute the correct size of the cell and get the height. This is where the magic happens.
CGFloat height = [cartItemCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
height += 1.0f
return height;
}
Take note that systemLayoutSizeFittingSize is wonky with UITextViews. In that case you have to compute the height of the entire cell manually using another way. There are also some performance optimizations you can do by caching the height per indexPath.
This blog post has a a more detailed description on what to do but the gist is essentially what I mentioned above. : http://johnszumski.com/blog/auto-layout-for-table-view-cells-with-dynamic-heights
I have created some sample code for dynamic tableview cell height with auto layout. You can download the project using following link.
DynamicTableViewCellHeight
I hope this will help you.

Resources