Objective-C UIScrollView constraints - objective-c

I have an UIScrollview which will contain X views, each view is of Class type "CategoryPostView" that contains an UIImageView. I am adding these views on the scrollView one after another. But when the image loads in the imageView I want to change the size of my imageView, therefor I want to change the Offset y of my all other views in the scrollView.
I am using autolayout constraint on UIScrollView but I couldn't reach to any result. This is the code I am using:
int categoryScrollY = 0.0;
CategoryPostView *previousView = nil;
for(; self.indexOfCate
goryInTheScroll < [self.categoryItemsArray count]; self.indexOfCategoryInTheScroll++){
PostItem *postItemObj = [self.categoryItemsArray objectAtIndex:self.indexOfCategoryInTheScroll];
CategoryPostView *categoryPostViewObj = [[CategoryPostView alloc] initWithFrame:CGRectMake(0.0, categoryScrollY, 148.0, 76.0)];
categoryPostViewObj.translatesAutoresizingMaskIntoConstraints = NO; //This part hung me up
[categoryPostViewObj setupPostViewWithItem:postItemObj];
[self.categoriesScrollView addSubview:categoryPostViewObj];
categoryScrollY += 80.0;
[_categoriesScrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[categoryPostViewObj]"
options:0 metrics:nil
views:#{#"categoryPostViewObj":categoryPostViewObj}]];
if (!previousView) { // first one, pin to top
[self.categoriesScrollView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[categoryPostViewObj]"
options:0 metrics:nil
views:#{#"categoryPostViewObj":categoryPostViewObj}]];
}else{
[self.categoriesScrollView addConstraints:
[NSLayoutConstraint
constraintsWithVisualFormat:#"V:[previousView][categoryPostViewObj]"
options:0 metrics:nil
views:#{#"categoryPostViewObj":categoryPostViewObj, #"previousView":previousView}]];
}
if(self.indexOfCategoryInTheScroll == ([self.categoryItemsArray count] - 1))
{
[self.categoriesScrollView addConstraint:[NSLayoutConstraint constraintWithItem:categoryPostViewObj
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self.categoriesScrollView
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0]];
}
previousView = categoryPostViewObj;
}
For now, I have the views on top of each other. I have to somehow apply my constraint from the bottom of the previous view and not from the top of the previous view. I guess I should add options to this line of code:
[self.categoriesScrollView addConstraints:
[NSLayoutConstraint
constraintsWithVisualFormat:#"V:[previousView][categoryPostViewObj]"
options:0 metrics:nil
views:#{#"categoryPostViewObj":categoryPostViewObj, #"previousView":previousView}]];
Many thanks!

The best way to use constraints inside a UIScrollView is to not use them at all.
If you want to layout the inside of the scroll view using constraints then create a UIView to contain everything in the scroll view and then place this view into the scroll view.
By doing this you can now use the container view that you created to place all the constraints inside.

I ended up using the class UIView+AutoLayout.
You can find it here https://github.com/smileyborg/UIView-AutoLayout and https://github.com/jrturton/UIView-Autolayout

Related

NSPopover and adding spacing with NSStatusItem

I am working on a menubar app, that uses NSPopover. I am using the following code to present popover.
[self.mainPopover showRelativeToRect:[testView bounds] ofView:testView preferredEdge:NSMinYEdge];
Issue is this is being present too close to status bar as shown below.
Even if i change the rect it does not have any effect and rightly so, as the documentation states
The rectangle within positioningView relative to which the popover should be positioned. Normally set to the bounds of positioningView. May be an empty rectangle, which will default to the bounds of positioningView.
Following is the screenshot from dropbox app, was just wondering how can i add some spacing in my app like dropbox.
To achieve this i added a padding view and attach set NSStatusItem View to that container view. Code from the solution used is as follow for anybody looking to implement it.
_paddingView = [NSView new];
[_containerView addSubview:_paddingView];
[_containerView addSubview:_dragView];
[_dragView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_paddingView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[_dragView(22)][_paddingView(5)]|" options:0
metrics:nil views:views]];
[_containerView addConstraint:[NSLayoutConstraint constraintWithItem:_dragView
attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual
toItem:_paddingView attribute:NSLayoutAttributeLeft
multiplier:1. constant:0]];
[_containerView addConstraint:[NSLayoutConstraint constraintWithItem:_dragView
attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
toItem:_paddingView attribute:NSLayoutAttributeRight
multiplier:1. constant:0]];
self.mainPopover = [[NSPopover alloc] init];
self.mainPopover.delegate = self;
self.mainPopover.backgroundColor = [NSColor greenColor];
[self.mainPopover setAnimates:NO];
[self.mainPopover setBehavior:NSPopoverBehaviorTransient];
[self.mainPopover setContentViewController:viewController];
[_containerView layoutSubtreeIfNeeded];
[_statusItem setView:_containerView];
You could inset the test view bounds to add some margin between de view and popover:
NSPopover *mainPopover = [self mainPopover];
NSRect bounds = CGRectInset([testView bounds], -50.0, -50.0);
[mainPopover showRelativeToRect:bounds ofView:testView preferredEdge:NSMinYEdge];

UIScrollView Not scrolling in iOS11

I have created a UIScrollView in code and it works in iOS10. I updated my Xcode today and it is no longer scrolling in iOS11 (simulator is iOS11 and does not work; physical iPad is still iOS10 and works).
User can add subviews when they want. When its the first subview, I anchor it to the left side, top and bottom of the scroll view. Then I anchor the right side of the subview to the right side of the scroll view which gives the contentSize its size and so it knows it needs to enable scrolling
UIScrollView *scrollViewMain = [UIScrollView new];
scrollViewMain.delegate = self;
scrollViewMain.backgroundColor = [UIColor greenColor];
scrollViewMain.translatesAutoresizingMaskIntoConstraints = NO;
scrollViewMain.directionalLockEnabled = YES;
self.scrollViewMain = scrollViewMain;
... // other code
if (self.countPlayers == 1) {
[self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[playerCardView(400)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(playerCardView)]];
[self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-20-[playerCardView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(playerCardView)]];
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self.scrollViewMain attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:playerCardView attribute:NSLayoutAttributeRight multiplier:1 constant:10];
self.constraintScrollViewRight = constraint;
[self.scrollViewMain addConstraint:constraint];
}
else {
[self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[previousPlayerCardView]-[playerCardView(==previousPlayerCardView)]" options:0 metrics:nil views:#{#"previousPlayerCardView": player.previousPlayer.playerViewCard, #"playerCardView": player.playerViewCard}]];
[self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-20-[playerCardView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(playerCardView)]];
}
if (self.constraintScrollViewRight) {
[self.scrollViewMain removeConstraint:self.constraintScrollViewRight];
}
NSLayoutConstraint *constraintRight = [NSLayoutConstraint constraintWithItem:self.scrollViewMain attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:playerCardView attribute:NSLayoutAttributeRight multiplier:1 constant:10];
self.constraintScrollViewRight = constraintRight;
[self.scrollViewMain addConstraint:constraintRight];
[self.scrollViewMain layoutIfNeeded];
DLog(#"self.scrollViewMain: %#", self.scrollViewMain);
DLog(#"self.scrollViewMain.contentSize: %#", NSStringFromCGSize(self.scrollViewMain.contentSize));
The contentSize does become larger then the scroll view's frame:
2017-10-04 20:01:58.479446-0500 [ViewController addPlayer]_block_invoke [Line 242] self.scrollViewMain: <UIScrollView: 0x7fa9fd01b000; frame = (286 20; 462 1014); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x60000005ff20>; layer = <CALayer: 0x600000233580>; contentOffset: {0, 0}; contentSize: {826, 89}; adjustedContentInset: {0, 0, 0, 0}>
2017-10-04 20:01:58.479969-0500 [ViewController addPlayer]_block_invoke [Line 243] self.scrollViewMain.contentSize: {826, 89}
Why does iOS11 break my code?
EDIT:
Also, I try to scroll to the right to show the new subview when it appears:
[self.scrollViewMain scrollRectToVisible:playerCardView.frame animated:YES];
And it does nothing.
SOLUTION:
I changed
[self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[playerCardView(200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(playerCardView)]];
To
[self.scrollViewMain addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollViewMain attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:playerCardView attribute:NSLayoutAttributeLeft multiplier:1 constant:10]];
The UIScrollView now has a left and right anchor and can calculate its contentSize.
Kind of a crappy bug that the Visual Format is partially broken now.
Why does iOS11 break my code?
Because that is Apple's job.
Try creating all your constraints without using NSLayoutConstraint constraintsWithVisualFormat:
I've just had the exact same problem in my app on iOS 11, after upgrading to XCode 9.
After several hours of trying to find out what constraint caused the problems in my code, I happened to replace all calls to NSLayoutConstraint constraintsWithVisualFormat: with building the constraints "by code" using NSLayoutConstraint constraintWithItem: instead; and now it works as it's supposed to...
I guess Apple has modified the visual format analyzer in a way that causes some unexpected side effects...

How to add a slide-in view effect?

How can I create this simple slide-in from the bottom view effect?
*
I have an action sheet method and i want to create this view controller effect that when i tap on one of the action sheet buttons i will have this view sliding in from the bottom of the screen, i dont need for you to explain to me how to add the date picker, only the effect of the view that sliding in and the background is darker when it slides and get liter when its dismissed
Please help me do that :))
this is my action sheet method where i want to perform this(instead of the modal):
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"first button was pressed");
} else if (buttonIndex == 1) {
MyViewController *myViewController = [[MyViewController alloc]initWithNibName:#"MyViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:myViewController];
[self.navigationController presentViewController:navigationController animated:YES completion:nil];
}
}
Here's an autolayout approach:
Create a "cover view" with a dark transparent background and constrain it to fill the window. Insert it above all other views.
Create the view containing the date picker and add it to the window above the cover view with a top constraint to the bottom of the window.
Call layoutIfNeeded() on the date picker view to trigger auto layout. Now the view is positioned "below" the screen and not yet visible to the user.
Remove the top constraint and add a bottom constraint to the bottom of the window.
Call layoutIfNeeded() again inside an animation block and the view will slide up from the bottom of the screen to its final position. You can also fade in the cover view within the animation block.
Here's a quick example. I haven't tested this exact code, but I've done this kind of thing many times and you should be able to get something from this approach I hope! Please note this assumes the MyActionSheet has a valid intrinsicContentSize.
// Create cover view
coverView = [UIView new];
coverView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.4];
coverView.alpha = 0.0;
// Add to window
[window addSubview:coverView];
[window bringSubviewToFront:coverView];
// Pin to edges
[window addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[coverView]|" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(coverView)]];
[window addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[coverView]|" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(coverView)]];
// Create action sheet
MyActionSheet *sheet = [MyActionSheet new];
[window insertSubview:sheet aboveSubview:coverView];
// Add horizontal constraints
[window addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[sheet]|" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(sheet)]];
// Pin to starting position
NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:sheet attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:window attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
[window addConstraint:topConstraint];
// Layout to start
[sheet layoutIfNeeded];
// Pin to final position
[window removeConstraint:topConstraint];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:sheet attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:window attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
[window addConstraint:bottomConstraint];
// Animate to final position
[UIView animateWithDuration:0.3 animations:^{
coverView.alpha = 1.0;
[sheet layoutIfNeeded];
}];
If you don't want to use auto layout for some reason, you can manually adjust the frames of the views provided you can calculate the height of the action sheet.

Can't get a UIImageView fill the parent UIView with autolayout

I'm trying to fill a UIView with a UIImageView using auto layout. I've tried several thing, but the most obvious, equalSize with parent view only works when I set the correct size in "Simulated metric". If I let Freeform (the point of autolayout isn't it ?) I get messed up.
I'm testing on an iPhone 4S and a 6 plus.
Thanks for any leading tracks.
EDIT FOR #mittens
I've seen your edit. I still can get it working. As you see I have 4 margin constraints, the same as in your code (I did not need the rest because I only use the main UIView).
Anyway, when I change the size on xcode, the layout is perfect, when I send it to my 4S, I only get Top and left margins.
I'd double check the constraints on the UIView you're trying to fill with the UIImageView to make sure it is filling up its parent view as it should be when the storyboard/xib is set to freeform. Also if you're adding/creating the views programmatically double check that the views 'translatesAutoresizingMaskIntoConstraintsis set toNO`. That always trips me up.
I made a super quick view and added some constraints to both a view inside the View Controllers view and an Image view to show one way to do it -- hopefully it helps at least a little
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.backdropView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
self.backdropView.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.5];
self.backdropView.translatesAutoresizingMaskIntoConstraints = NO; // Make sure this is set to NO if the view is being added programmatically
[self.view addSubview:self.backdropView]; // Always add the view into the hierarchy _before_ constraints are added (again, if creating & adding programmatically)
NSLayoutConstraint *backdropViewWidth = [NSLayoutConstraint constraintWithItem:self.backdropView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.backdropView.superview attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0];
NSLayoutConstraint *backdropViewHeight = [NSLayoutConstraint constraintWithItem:self.backdropView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.backdropView.superview attribute:NSLayoutAttributeHeight multiplier:0.5 constant:0];
NSLayoutConstraint *backdropViewCenterX = [NSLayoutConstraint constraintWithItem:self.backdropView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.backdropView.superview attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
NSLayoutConstraint *backdropViewCenterY = [NSLayoutConstraint constraintWithItem:self.backdropView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.backdropView.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
[self.backdropView.superview addConstraints:#[backdropViewWidth, backdropViewHeight, backdropViewCenterY, backdropViewCenterX]];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
self.imageView.translatesAutoresizingMaskIntoConstraints = NO;
self.imageView.backgroundColor = [UIColor colorWithRed:1 green:0 blue:1 alpha:0.5];
[self.backdropView addSubview:self.imageView];
NSLayoutConstraint *imageViewTop = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.imageView.superview attribute:NSLayoutAttributeTop multiplier:1 constant:8];
NSLayoutConstraint *imageViewLeft = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.imageView.superview attribute:NSLayoutAttributeLeft multiplier:1 constant:8];
NSLayoutConstraint *imageViewRight = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.imageView.superview attribute:NSLayoutAttributeRight multiplier:1 constant:-8];
NSLayoutConstraint *imageViewBottom = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.imageView.superview attribute:NSLayoutAttributeBottom multiplier:1 constant:-8];
[self.imageView.superview addConstraints:#[imageViewTop, imageViewLeft, imageViewRight, imageViewBottom]];
[self.view layoutIfNeeded];
}
That produces and
Again, hopefully this helps.
EDIT: how to add them in storyboard
Note on photo 3, I select the view I want to constrain and then shift select the view I want to constraint it to. So I selected the inside UIView (because it width/height will be constrained to the parent view) then shift selected its parent view (the view it is nested inside of) to enable those options of Equal Width & Equal Height
Add constraints to UIImageView nested inside the UIView
Center UIView inside its parent view
Add width/height constraints equal to parent -- Note: I select the view I want to constrain and then shift select the view I want to constraint it to. So I selected the inside UIView (because it width/height will be constrained to the parent view) then shift selected its parent view (the view it is nested inside of) to enable those options of Equal Width & Equal Height
Change multiplier in constraint to be whatever you want, 0.5 in this case
Celebrate
i'm not sure but try this in your imageview.
[imgView clipToBounds:YES];
I hope it's work for you

Setting a label to UITableView's tableFooterView - with autolayout

When my table view is empty, I want to add a simple label into the tableview footer to display a "no content" message. It was working fine when I was setting the frames of the UILabel and the UIView that I used for footerView, but now I'm trying to convert to using auto-layout, and I can't get it to work.
Here's what I'm doing:
// Create the footer
UIView *tempFooter = [[UIView alloc] init];
UILabel *atext = [[UILabel alloc] init];
tempFooter.translatesAutoresizingMaskIntoConstraints = NO;
atext.translatesAutoresizingMaskIntoConstraints = NO;
atext.numberOfLines = 0;
[atext setText:#"Add Some Text"];
atext.textAlignment = NSTextAlignmentCenter;
atext.font = [UIFont italicSystemFontOfSize:14];
atext.textColor = [UIColor grayColor];
atext.backgroundColor = [UIColor clearColor];
atext.lineBreakMode = NSLineBreakByWordWrapping;
// add label to footer view, and add constraints
[tempFooter addSubview:atext];
NSLayoutConstraint *tvatt1 = [NSLayoutConstraint constraintWithItem:tempFooter
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:atext attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:10.0];
NSLayoutConstraint *tvatt2 = [NSLayoutConstraint constraintWithItem:tempFooter
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:atext
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:10.0];
NSLayoutConstraint *tvatt3 = [NSLayoutConstraint constraintWithItem:tempFooter
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:atext
attribute:NSLayoutAttributeTop
multiplier:5.0
constant:0];
NSLayoutConstraint *tvatt4 = [NSLayoutConstraint constraintWithItem:tempFooter
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:atext
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant: 0];
[tempFooter addConstraints: #[tvatt1, tvatt2, tvatt3, tvatt4]];
// set the footerview
self.tview.tableFooterView = tempFooter;
When I run this, I get a crash:
2014-09-08 19:57:16.594 SimpleList[49442:60b] * Assertion failure in
-[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794 2014-09-08
19:57:21.073 SimpleList[49442:60b] * Terminating app due to uncaught
exception 'NSInternalInconsistencyException', reason: 'Auto Layout
still required after executing -layoutSubviews. UITableView's
implementation of -layoutSubviews needs to call super
I'm not sure what I'm doing wrong. I've also tried setting constraints for the self.tview.tableFooterView wrt the tempFooter (pinning against all 4 sides) but that doesn't change the crash. I also call:
[self.tview.tableFooterView layoutSubviews];
but that doesn't help either.
Any ideas what I'm doing wrong?
You shouldn't set translatesAutoresizingMaskIntoConstraints to NO for table views, their cells, or table header and footer views (or for your controller's self.view for that matter). It's ok to use constraints for views inside those views (the content view of cells or the header and footer views). I added a simplified version of your code to viewDidLoad, and it worked as expected. Note that you need to give the footer view a height and an x position (the y position and the width are ignored),
UIView *tempFooter = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 50)];
UILabel *atext = [[UILabel alloc] init];
atext.translatesAutoresizingMaskIntoConstraints = NO;
atext.numberOfLines = 0;
[atext setText:#"Add Some Text"];
atext.textAlignment = NSTextAlignmentCenter;
atext.font = [UIFont italicSystemFontOfSize:14];
atext.textColor = [UIColor grayColor];
atext.backgroundColor = [UIColor clearColor];
atext.lineBreakMode = NSLineBreakByWordWrapping;
[tempFooter addSubview:atext];
NSDictionary *dict = NSDictionaryOfVariableBindings(atext);
[tempFooter addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|-10-[atext]-10-|" options:0 metrics:nil views:dict]];
[tempFooter addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[atext]|" options:0 metrics:nil views:dict]];
self.tableView.tableFooterView = tempFooter;
I'm not sure what you were trying to accomplish with your constraint, tvatt3. The multiplier (you have 5) doesn't do anything with a top or left constraint since the value of those attributes is 0. I used the visual constraints, rather than the method you used, but when I used your code to add the constraints, it worked also .
Interestingly, changing the Autoresizing mask in the xib solved my problem.
Constraints not working:
Working:
I was able to make dynamically auto layout table footer width and height by implementing #rdelmar solution for constraints and adding these lines below. Same solution applies to table header view.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let tableFooter = tableView.tableFooterView {
let maxSize = CGSize(width: self.tableView.bounds.size.width,
height: CGFloat.greatestFiniteMagnitude)
let size = tableFooter.systemLayoutSizeFitting(maxSize)
let height = size.height
var headerFrame = tableFooter.frame
// If we don't have this check, viewDidLayoutSubviews() will get
// repeatedly, causing the app to hang.
if height != headerFrame.size.height {
headerFrame.size.height = height
tableFooter.frame = headerFrame
tableView.tableFooterView = tableFooter
}
}
}
P. S. I prefer Interface Builder for constraints setup
hope this will help you
I am not sure of this but it help me in my project, first add every thing in contentView (all the subview and the constraint)
[self.contentView addSubview:atext]
and then comes to code part
NSLayoutConstraint *tvatt1 = [NSLayoutConstraint constraintWithItem:tempFooter
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:atext attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:10.0];
code saying for left attribute
temfooter(must be equal) = 1.0*atext +10.0
i.e
temfooter must be equal to the modified atext , so need to make sure that your constraints are not wrong.