UITableView header height will not change in storyboard - ios

I have a Storyboard that is using a UITableViewController. I have added a UIView as the UITableView header and set the height to 200. But, for some reason, when I preview it, the header is huge! looks to be about 540 high (header is white):
Here are my settings:
It looks correct in the storyboard preview. What could be causing it to be so huge and prevent my height setting from working?

Apple figured it out. Here is what they said:
Because the frame of a view can not be customized per-size class, you
need to make changes to your header view's frame while editing the
[wAny hAny] size class.
I was in the [wCompact hRegular] mode, which apparently you cannot set frame sizes in.

Just solved this question, try this:
UIView *v = self.tableView.tableHeaderView;
CGRect fr = v.frame;
fr.size.height = [UIScreen mainScreen].bounds.size.height -100;
v.frame = fr;
[self.tableView updateConstraintsIfNeeded];
Can't set constraints of UItableView's tableHeaderView height by autolayout in Storyboard

For me in order to make it work, I needed to create an IBOutlet reference to the header view. Then I added in the viewDidLoad:
self.header.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 40);
self.tableView.sectionHeaderHeight = 0;

You have to take a seperate NibFile and resize the nib file as per your required size (Resize the height manually do not use attribute inspector.). Change Simulated metrics to freeform in attribute inspector.
Then You can customize the HeaderView .
static NSString *SectionHeaderViewIdentifier = #"SectionHeaderViewIdentifier";
#define HEADER_HEIGHT 200
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.sectionHeaderHeight = HEADER_HEIGHT;
// Set up default values.
self.tableView.sectionHeaderHeight = HEADER_HEIGHT;
UINib *sectionHeaderNib = [UINib nibWithNibName:#"SectionHeaderView" bundle:nil];
[self.tableView registerNib:sectionHeaderNib forHeaderFooterViewReuseIdentifier:SectionHeaderViewIdentifier];
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *sectionHeaderView = [self.tableView dequeueReusableHeaderFooterViewWithIdentifier:SectionHeaderViewIdentifier];
//You can customize your header view
return sectionHeaderView;
}

Related

How to increase UIView height in UItableView using Objective C?

I am new to iOS Programming, I have implemented UITableviewController. I placed UIView inside of UITableView. I designed label, textfields and tableview inside of UIView. Here My problem is, When I increasing the dynamic tableview based on array count, I want to increase my UIView height also. I don't know how to do that?? Below is my design structure,
UITableViewController---
UIView----- (1)
Label---Label (2)
label---Label (3)
label--- (4)
UItableview (5)
textfield (6)
textfield (7)
and so on
below I have successfully increase the (5) height and also I want to increase (1) height I don't know how to do?? can any one suggest solution for this?? I have tried this below code.
-(void)viewDidLayoutSubviews{
CGFloat numberofrows=creditList.count;
height = numberofrows*propertytable.rowHeight;
_tableviewheight.constant = height;
propertytable.frame =CGRectMake(propertytable.frame.origin.x,propertytable.frame.origin.y, propertytable.frame.size.width,_tableviewheight.constant);
CGRect myviewframe=mainview.frame;
NSLog(#"The myviewframe value is %f",myviewframe.size.height);
mainview.translatesAutoresizingMaskIntoConstraints=YES;
myviewframe.size.height=5000;
mainview.frame=myviewframe;
mainview.frame = CGRectMake(0,0,mainview.frame.size.width, 5000);
mainview.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
mainview.contentMode = UIViewContentModeScaleAspectFit;
[mainview layoutIfNeeded];
}
If object has autolayout, try this:
- (void)viewDidLoad {
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 105; //Default Height
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}

Dynamically resize UICollectionView's supplementary view (containing multiline UILabel's)

Inside a UICollectionView's supplementary view (header), I have a multiline label that I want to truncate to 3 lines.
When the user taps anywhere on the header (supplementary) view, I want to switch the UILabel to 0 lines so all text displays, and grow the collectionView's supplementary view's height accordingly (preferably animated). Here's what happens after you tap the header:
Here's my code so far:
// MyHeaderReusableView.m
// my gesture recognizer's action
- (IBAction)onHeaderTap:(UITapGestureRecognizer *)sender
{
self.listIntro.numberOfLines = 0;
// force -layoutSubviews to run again
[self setNeedsLayout];
[self layoutIfNeeded];
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.listTitle.preferredMaxLayoutWidth = self.listTitle.frame.size.width;
self.listIntro.preferredMaxLayoutWidth = self.listIntro.frame.size.width;
[self layoutIfNeeded];
CGFloat height = [self systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
self.frame = ({
CGRect headerFrame = self.frame;
headerFrame.size.height = height;
headerFrame;
});
NSLog(#"height: %#", #(height));
}
When I log height at the end of layoutSubviews, its value is 149 while the label is truncated and numberOfLines is set to 3. After tapping the headerView, setting numberOfLines to 0, and forcing a layout pass, height then gets recorded as 163.5. Great!
The only problem is that the entire headerView doesn't grow, and the cells don't get pushed down.
How can I dynamically change the height of my collectionView's supplementary view (preferably animated)?
I'm aware of UICollectionViewFlowLayout's headerReferenceSize and collectionView:layout:referenceSizeForHeaderInSection: but not quite sure how I'd use them in this situation.
I got something working, but I'll admit, it feels kludgy. I feel like this could be accomplished with the standard CollectionView (and associated elements) API + hooking into standard layout/display invalidation, but I just couldn't get it working.
The only thing that would resize my headerView was setting my collection view's flow layout's headerReferenceSize. Unfortunately, I can't access my collection view or it's flow layout from my instance of UICollectionReusableView, so I had to create a delegate method to pass the correct height back.
Here's what I have now:
// in MyHeaderReusableView.m
//
// my UITapGestureRecognizer's action
- (IBAction)onHeaderTap:(UITapGestureRecognizer *)sender
{
self.listIntro.numberOfLines = 0;
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.listTitle.preferredMaxLayoutWidth = self.listTitle.frame.size.width;
self.listIntro.preferredMaxLayoutWidth = self.listIntro.frame.size.width;
CGFloat height = [self systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
self.frame = ({
CGRect headerFrame = self.frame;
headerFrame.size.height = height;
headerFrame;
});
if (self.resizeDelegate) {
[self.resizeDelegate wanderlistDetailHeaderDidResize:self.frame.size];
}
}
// in my viewController subclass which owns the UICollectionView:
- (void)wanderlistDetailHeaderDidResize:(CGSize)newSize
{
UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
// this is the key line
flowLayout.headerReferenceSize = newSize;
// this doesn't look beautiful but it's the best i can do for now. I would love for just the bottom of the frame to animate down, but instead, all the contents in the header (the top labels) have a crossfade effect applied.
[UIView animateWithDuration:0.3 animations:^{
[self.collectionView layoutIfNeeded];
}];
}
Like I said, not the solution I was looking for, but a working solution nonetheless.
I ran into the same issue than you, so I was just wondering: did you ever get a solution without the crossfade effect that you mention in the code sample?. My approach was pretty much the same, so I get the same problem. One additional comment though: I managed to implement the solution without the need for delegation: What I did was from "MyHeaderReusableView.m" You can reference the UICollectionView (and therefore, the UICollectionViewLayout) by:
//from MyHeaderReusableView.m
if ([self.superview isKindOfClass:UICollectionView.class]) {
//get collectionView reference
UICollectionView * collectionView = (UICollectionView*)self.superview;
//layout
UICollectionViewFlowLayout * layout = (UICollectionViewFlowLayout *)collectionView.collectionViewLayout;
//... perform the header size change
}

None option not included in simulated metrics

I've been trying to load my headerView.xib file onto my BNRItemViewControlelr file which already has its on view.
I am just adding my headerView file onto the BNRItemViewController view. However when I look in the simulated metrics to try and to edit the size of the view there ins't a none option, instead just a freeform which still doesn't change the actual view at runtime. Is there a way I could change it?
(I can't currently post the pictures because I need 10 reputation points)
Just set the frame directly in the code, like this:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"UITableViewCell"];
// Adding top margin to the header view
UIEdgeInsets inset = UIEdgeInsetsMake(20, 0, 0, 0);
self.tableView.contentInset = inset;
UIView *header = self.headerView;
// making the frame for the header view
header.frame = CGRectMake(0, 0, 400, 57);
[self.tableView setTableHeaderView:header];
}
I actually found the answer in this stackoverflow thread: Adding constraint to a UITableVIew headerview
to add top margin: Top margin on UITableViewController
we are using UIEdgeInsets

UITableViewHeaderFooterView and Interface Builder: how to adjust width for different devices?

I am implementing a custom Header view for my UITableView. I created a HeaderView class that extends UITableViewHeaderFooterView and a Nib file for this view.
In the view controller, I registered it:
[self.tableView registerNib:[UINib nibWithNibName:#"HeaderView" bundle:[NSBundle mainBundle]] forHeaderFooterViewReuseIdentifier:#"HeaderView"];
And then set as a header:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
HeaderView *view = [tableView dequeueReusableHeaderFooterViewWithIdentifier:#"HeaderView"];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 26.0f;
}
The problem is that the width of the view is always the same as in the nib file. Since now there are multiple screen widths, I cannot simply set the view width to 320 (or the width of the table view) in the nib file.
How exactly am I supposed to set up the header view so it automatically fits the table width?
Update: here's a comparison when I change the view simulated metrics from Inferred to a fixed one (iPhone 3.5" in this case):
img http://cl.ly/image/451n2N303J3S/Image%202015-04-19%20at%206.39.58%20PM.png
Had the same problem ... the only solution I found was by setting all the frames of the subviews in my custom UITableViewHeaderFooterView to the according state.
Dirty example:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
NSString *headerIdentifier = #"SectionHeader";
TableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerIdentifier];
if (headerView == nil) {
headerView = [[TableViewHeaderFooterView alloc] initWithReuseIdentifier:headerIdentifier];
}
.....
[headerView setWidthForSubviews:tableView.frame.size.width]; // set the right width of the right subviews
....
return headerView;
}
in TableViewHeaderFooterView
- (void)setWidthForSubviews:(CGFloat)width {
for (UIView *view in #[[self viewWithTag:1],[self viewWithTag:2],[self viewWithTag:3], ...]) {
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, width, view.frame.size.height);
}
}
If someone finds another solution I'll be grateful but it seems that UITableViewHeaderFooterView may have problems with autolayout, especially if you load it from a nib.
I would look at a couple of things.
If you using springs and struts, then trying set the autoResizingMask
[maskingBackground setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
If using autolayout then pin to the tableWidth and use a constant height constraint.
If that does not meet your needs I would look at using this in your header view class
-(void)willMoveToSuperview:(UIView*)superview
And setting your frame in there using the superview.frame.size to guide you.

how to change height of uiview defined in storyboard

Update: I ended up implementing the code below into it's own method and then called it from viewDidLayoutSubviews and willAnimateRotationToInterfaceOrientation. Doing it from viewDidAppear (as suggested) would not resize the view when returning from a segue.
I have a UIView defined in a storyboard which I'm using for a header view on my UIViewController. I have a constant in my code for all header views to be 80 units high. I have a tag on the storyboard header view of 200. I thought I could use this tag to get the view, modify the height of the underlying CGRect, and then re-set the header view to the modified CGRect. That doesn't seem to affect the height however. What am I missing?
- (void)viewDidLoad
{
UIView *header = [self.view viewWithTag:200];
CGRect hrect = [header frame];
hrect.size.height = HEADER_HEIGHT;
[header setFrame:hrect];
...
Try to do that on viewDidAppear then call
[self setNeedsLayout]
The problem is that you're using the tag as an NSString. The tag property is an NSInteger. Try doing the following:
- (void)viewDidLoad
{
UIView *header = [self.view viewWithTag:200];// give the tag as an int
CGRect hrect = [header frame];
hrect.size.height = HEADER_HEIGHT;
[header setFrame:hrect];
...
Also, make sure the tag you defined in the Storyboard is also 200 and not #"200".
Hope this helps!

Resources