UITableViewAutomaticDimension on custom UITableViewCell - ios

I am using UITableViewAutomaticDimension for multiline UILabel in UITableViewCell and everything works fine on iPhone. To add a margin to the table view on iPad I'm using a custom subclass overriding setFrame:
- (void)setFrame:(CGRect)frame {
if (IS_IPAD) {
CGFloat inset = 100;
frame.origin.x += inset;
frame.size.width -= 2 * inset;
}
[super setFrame:frame];
}
The problem is, that the UITableViewAutomaticDimension is returning the wrong (too small) height for the cell on iPad and the label gets cut off. I assume it's returning the height calculated for the full width.
Is there any way to get the table view calculate the right height?
EDIT:
found a quite hacky solution, but this does not work when setting attributedText
- (void)setFrame:(CGRect)frame {
if (IS_IPAD) {
CGFloat inset = 100;
frame.origin.x += inset;
frame.size.width -= 2 * inset;
for (UIView *subview in self.contentView.subviews) {
if ([subview isKindOfClass:[UILabel class]]) {
UILabel *label = (UILabel *)subview;
if (label.numberOfLines == 0) {
label.preferredMaxLayoutWidth = frame.size.width;
}
}
}
}
[super setFrame:frame];
}

If you are doing something like this. Combining technology of Size Classes and Auto-Layout is able to solve the problem in a very easy way. Otherwise, it will require a lot of redrawing and calculation when you want to do that in a manual way. Also, when you are using UITableViewAutomaticDimension, you should go with this way as well because this flag simply indicates that iOS should calculate the cell height automatically via Auto-Layout.

Related

iOS8 How dynamically fixed UITableViewHeaderFooterView height size?

I use the method as follows
I have just tried below lines of code, dynamically set the UITableViewHeaderFooterView height size.
self.tableView.estimatedSectionHeaderHeight = 100
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
I have the following problems
In iOS9, iOS10 can run normally, and can display properly. But can not be displayed correctly in iOS8, and the following error is displayed:
My analysis is as follows:
From the error prompt, I can see that the problem is NSLayoutConstraint: 0x7f8498d7b890 _UITableViewHeaderFooterContentView: 0x7f8498cb9200.height == 0
But I have never made any Constraints to UITableViewHeaderFooterContentView
How should I fit iOS8?
You need to use the UIView systemLayoutSizeFittingSize:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[ViewHeader setNeedsLayout];
[ViewHeader layoutIfNeeded];
CGFloat height = [ViewHeader systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
CGRect headerFrame = ViewHeader.frame;
headerFrame.size.height = height;
ViewHeader.frame = headerFrame;
[tbl setTableHeaderView:ViewHeader];
}

Implementing iPad General Setting Page

So far I have customized the tableview and implemented the iPad General Setting Page. Below is the code for tableview which will change frame accordingly. But the issue is when I insert/delete rows or section in the tableview. My tableviewcell backgroundview (not cell) width get shrinks. Any idea what wrong am I doing here?
- (void)setFrame:(CGRect)frame
{
if (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
CGFloat inset =10;
frame.origin.x += inset;
frame.size.width -= 2 * inset;//The issue is in this line
}
[super setFrame:frame];
}
I found the simple solution to achieve this. No need of customizing UITableView subclass. Just take the outlet of tableview and set the frame and change the color of backgroundview. like that below:-
CGFloat tableBorderLeft = 10;
CGFloat tableBorderRight = 10;
CGRect tableRect = self.view.frame;
tableRect.origin.x += tableBorderLeft; // make the table begin a few pixels right from its origin
tableRect.size.width -= tableBorderLeft + tableBorderRight; // reduce the width of the table
yourTableView.frame = tableRect;
self.view.backgroundColor=[UIColor colorWithRed:(239/255.0f) green:(239/255.0f) blue:(244/255.0f) alpha:1.0];

tableHeaderView with Autolayout not working correctly

Hey everybody i have a TableHeaderView and everything gets managed by Autolayout:
The UIImageView at the top should be always 2:1, so i set the Aspect ration and the Rest of the needed Constraints.
The 4 UIButtons should be always horizontal and should have the same Height and Width. So i worked with Equal Width and Equal Height and also with a Aspect Ratio of 1:1
And i have two UILabels with numberOfLines set to 0. I also made a Subclass of my UILabel, because of the preferredMaxLayoutWidth, like this:
- (void) layoutSubviews
{
[super layoutSubviews];
if ( self.numberOfLines == 0 )
{
if ( self.preferredMaxLayoutWidth != self.frame.size.width )
{
self.preferredMaxLayoutWidth = self.frame.size.width;
[self setNeedsUpdateConstraints];
}
}
}
This is my Code:
- (void)initializeHeaderViewLabels
{
//After the Response from my server arrived i set the tableHeaderView with the Textdata
self.tableView.tableHeaderView = nil;
if((self.contentDict[#"title"]) != [NSNull null])
{
self.headerTitleLabel.text = (self.contentDict[#"title"]);
}
if((self.contentDict[#"shortDescription"]) != [NSNull null])
{
self.headerDescriptionLabel.text = (self.contentDict[#"shortDescription"]);
}
[self.headerView setNeedsLayout];
[self.headerView layoutIfNeeded];
CGFloat height = [self.headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = height;
self.headerView.frame = headerFrame;
[self.tableView setTableHeaderView:self.headerView];
}
I get my Image and the Text for the UILabels from my Server, so i have to wait until the Response arrives, then i call initializeHeaderViewLabels.
**My Problem is that the tableHeaderView is way too large during Runtime and so my UILabels get stretched and there is a lot of whiteSpace. Maybe i miss something?
In order to make it work you'll need some magic or migrate away from table header view. I've already answered on a similar question here. The trick is to magically reset tableHeaderView after evaluating it's height via autolayout. I've created sample project for that: TableHeaderView+Autolayout.
Try below solution
- (void)sizeHeaderToFit
{
UIView *header = self.tableView.tableHeaderView;
[header setNeedsLayout];
[header layoutIfNeeded];
CGFloat height = [header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
CGRect frame = header.frame;
frame.size.height = height;
header.frame = frame;
self.tableView.tableHeaderView = header;
}
Source:
table header view height is wrong when using auto layout, IB, and font sizes
Also refer below question...!
How do I set the height of tableHeaderView (UITableView) with autolayout?
My problem was that I was setting constraints on the my header view that were mapping some frame values to superview frame values. When I removed the constraints and just set the frame directly, everything worked.
Header view height is set in the table view delegate. By default it is the same size as in interface builder which is too large when run in app since the width for interface builder is 600.
So what you need is to implement this method in UITableViewDelegate
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 200.0 // Set the desired height based on your device or what ever you are using.
}
And Objective-C version:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 200.0f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 200;
}

Rect UITableViewCell in iOS 8 when beginupdate and endupdate

I'm building a UITableView with style tableview Grouped, and i give a gap (margin left) on method frame UITableViewCell like this
- (void)setFrame:(CGRect)frame {
if(IOS_7){ //above ios 6
CGFloat gap = 10.0f;
frame.origin.x += gap;
frame.size.width -= gap*2;
}
[super setFrame:frame];
}
the result like this.
and then after 5s, i did call method
[_table beginUpdates];
[_table endUpdates];
the result like this.
the gap on the right twice from my gap = (gap*2)
this problem only on ios 8,
is the iOS 8 call twice setFrame in uitableviewcell ?
and how to solve it ?
note:
- i have been tried with reset frame with CGRectMake(0.0f, frame.origin.y, [UIScreen mainScreen].bounds.size.width, frame.size.height); but if i'm using with ipad with left menu side, it's not solve my problem,
- does not use custom cell (just using default uitableviewcell)
You are setting the frame wrong. You should be doing this:
- (void)setFrame:(CGRect)frame {
if(IOS_7){ //above ios 6
CGFloat gap = 10.0f;
frame.origin.x += gap;
frame.size.width -= gap*2;
[super setFrame: frame];
}
}

how to resize UIScrollView to fit content of children UITextViews

I have a UIScrollView with a number of children UITextViews arranged vertically. I want the UIScrollView to resize to fit content. So my TextViews I do
- (void)textViewDidChange:(UITextView *)textView
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
textView.frame = newFrame;
[textView setNeedsLayout];
}
And for the scrollview I do
-(void)resizeScrollViewToFitContent
{
CGRect contentRect = CGRectZero;
for (UIView *view in self.scrollView.subviews) {
contentRect = CGRectUnion(contentRect, view.frame);
}
self.scrollView.contentSize = contentRect.size;
}
I call [self resizeScrollViewToFitContent] inside viewDidAppear. Any ideas why this setup is not working?
I am not sure how is the arrangement of your textViews inside the scrollView. I assume that they are arranged vertically right next to each other. I have created a sample project with a scrollView and 3 textViews and it works well with the following code:-
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
CGFloat height = self.textView1.frame.size.height +self.textView2.frame.size.height +self.textView3.frame.size.height ;
CGSize size = CGSizeMake(self.scrollView.frame.size.width, height);
self.scrollView.contentSize = size;
}
From my own project, the content Height of the scrollview is the combination of the height for all 3 textviews. It might be different in your project.
You shouldn't be doing the union of the contentFrame and view.frame. Try the following:
-(void)resizeScrollViewToFitContent
{
UIScrollView* scrollView;
CGSize contentSize = CGSizeZero;
for (UIView* subview in scrollView.subviews)
{
CGFloat subviewRight = CGRectGetMaxX(subview.frame);
if (subviewRight > contentSize.width)
{
contentSize.width = subviewRight;
}
CGFloat subviewBottom = CGRectGetMaxY(subview.frame);
if (subviewBottom > contentSize.height)
{
contentSize.height = subviewBottom;
}
}
scrollView.contentSize = contentSize;
}
One small thing worth noting: a UIScrollView's scroll indicators are subviews of any UIScrollView. This has the potential to throw off the above code's accuracy, but I've found that it always works except in some very particular cases.
If you know how many subviews are in your scrollview per row then you'll want to do a little math to find the correct height.
For example, you might have a uiview with a uiimageview and uilabel, so you're subview count will be 3 times what it should be.
try
// csv = contentscrollview
NSLog(#"%d", [[csv subviews] count] / 3);

Resources