Interface Builder Constraints - ios

I'm trying to create layout like this in interface builder.
I'm using constraints to make these views stretchable.
Top view has left, right and top space bound to superview, and bottom space to bottom view.
Bottom view has the left right and bottom space bound to superview.
On runtime I add ViewController views to both of them.
Issue here is that there is no constraint for Y of bottom view, IB shows red error arrow and so on. That is because I don't know exact height of it. Is there any "android wrap_content" constraint for yellow view to be with height which is equal to it's inner view added in runtime?

Add a constraint for the height of the yellow view. Then add an IBOutlet for that constraint so you can make changes to the constraint's constant value at runtime. If you need to calculate the size that satisfies the yellow view's constraints, you can use systemLayoutSizeFittingSize:.
Alternatively, you can rely on the yellow view's intrinsicContentSize. Add a placeholder Intrinsic Size for the view in Interface Builder. If your yellow view implements intrinsicContentSize or has constraints that give it an unambiguous height (e.g. if it contains a UILabel or UIImageView that is pinned at the top and the bottom), then that will be enough to appropriately size the view.

Just add height constraint to yellow view, for example:
NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:self.yellowView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeHeight
multiplier:0.20f
constant:0.0f];
heightConstraint.active = YES;

Related

How do I set width of custom subview to be 1/3rd of parent UIView which does not have width constraint?

I have a custom parent UIView (Say PView) which is defined by Left,Right,Top and Bottom constraints. Now I want to add a custom subview (say SView) to the PView with width equal to MIN of 200 and 1/3rd of PView.
I have the updateConstraints method in my PView class where I update the location constraints for SView. However, I am not sure how can I set its size, because I don't have the widthConstraint of PView?
You can easily achieve this by proportional width feature in storyboard with Autolayout.
Give you PView a proportional width to a ratio of 1:3 to your superView(SView).
Parent View Constraint
Child/SubView View Constraint
How to Give Proportional Constraint?
You set ParentView and ChildView with equal width then double click on width constraint and set a ratio of 1:3. Width will always be 1/3 of parent view
Coding Approach
[self.yourview addConstraint:[NSLayoutConstraint
constraintWithItem:self.yourview
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.yourview
attribute:NSLayoutAttributeWidth
multiplier:(self.yourview.frame.size.height / self.yourview.frame.size.width)
constant:0]];
Your parent view's constraint should be like : top,leading,trailing,bottom
Your subview's constraints should be like : top,leading,fixed height
Now select both view and set equal width constraint and then select that constraint and from attribute inspector change it's multiplier to 0.333.
That's it!
try using following code
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
sview. frame = CGRectMake(0,0,pview.frame/3,50);
}

AutoLayout two labels with 30:70 ratio proportional

I have two labels green and yellow and i am trying to make them always be in the same proportional to the screen width. I tried aspect ratio and changing the priority etc but not get the final result. I will be very thankful if someone can help me
You need to set up constraints for the widths of the views related to the width of the superview.
In your case:
Pin the left side of the green view to the view.
Pin the right side of the yellow view to the view.
Make the horizontal spacing between the green and yellow views to be zero.
Now create a constraint and apply it:
- (void)viewDidLoad {
[super viewDidLoad];
[self setupWidthConstraints];
}
- (void)setupWidthConstraints {
NSLayoutConstraint *widthConstraint;
widthConstraint = [NSLayoutConstraint constraintWithItem:self.greenView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:0.30
constant:0.0];
[self.view addConstraint:widthConstraint];
}
This constrains the green view's width to 30% of the view width. And since the yellow view is pinned to the side and the green view, it will take up the remaining 70%.
If you want to see this in action you can get an example project that demonstrates exactly this from https://bitbucket.org/abizern/so27659421/get/master.zip

iOS Autolayout: Align left edge of a UILabel with horizontal center in container?

So I'm trying to have a customized UITableViewCell that looks like the following:
And I'm trying to get the Detail labels to be left aligned and set the content hugging on the title labels higher.
So the challenge I have is that I want the left edge of the second column on Title cells to be aligned with the center of the whole view.
Is there a way to do that?
Try using a couple of grouping views, one for each column. Pin the outer edges of each column view to the edges of the cell content view, then add an equal-widths constraint to the column views.
Once you have your containing column views in place, you can layout the labels inside each.
Add equal widths constraint, add leading space constraint to left view, and trailing space to the right, and horizontal spacing between them.
Sure, you could put them in a UIView and that views left edge would be equal to CenterX and thus they would be aligned in the middle. Or you could just align the top title cell to CenterX and have the leading edge of each title match that. There are numerous ways you can achieve what your asking here.
NSLayoutContraint *constraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f];
[self.view addConstraint:constraint];
NSArray *constraints [NSLayoutConstraint
constraintsWithVisualFormat:#"V:|[label1]-(5)-[label2]-(5)-[label3]|"
options:NSLayoutFormatAlignAllLeading
metrics:nil
views:#{ #"label1" : label1, #"label2" : label2, #"label3" : label3 }];
[self.view addConstraints:constraints];
Above is just samples of how you could do it in the code if you wished too, self.view is a view but if you wanted the content view of the UITableViewCell you could just switch it out to that.
I couldn't get the suggestions above working so I did this another way.
InnerView1 50% width of ContentView & pinned to left
InnerView2 50% width of ContentView & pinned to right
Simple.

AutoLayout issue with resizing subviews

I'm trying to figure out how to use Autolayout and I've founded a problem. I want to create a view in IB with size 200x200. This view, called them PieView, has two UIImageViews with frames (0, 0, 200, 200), for both of them.
My question is, how to override updateConstraints in code (I like visual format language), or in IB, that if I change size of my PieView (for example to 100), and subviews will changed too (0, 0, 100, 100).
And how can I change the size of PieView, I'm trying for width and for height
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:100.f];//kDiameter * sizeCoef];
If the subviews of the container view (PieView) are correctly positioned/sized/pinned relative to their container, all you need to do is update the width of the container view (PieView).
To change the view's size in code, you'll need to make sure you keep a reference (in a property, for example) to the constraint on the view's width. So if you added that constraint in Xcode, that means connecting an outlet for that constraint. Or if you added it in code (as you have written in your question), just assign the constraint to a property instead of a local variable.
Then, in updateConstraints, change the constant property of the constraint to the new width. Here's an example:
- (void)updateConstraints
{
// Probably want to wrap the below line with a check for when you should actually do this change,
// as updateConstraints may get called more than once (including when you aren't ready to change the width).
self.widthConstraint.constant = 100.0f;
}
Then just call setNeedsUpdateConstraints on the view when you're ready to change its width!
I'm not sure that you even need to re-configure the height or width constraints for the image views. If you want the image views to grow and shrink with their superview, then just pin the the sides of the images views to the superview in IB. You would not need to override updateConstraints.

UIImageView and Auto Layout in Code

I'm trying to use programmatic visual constraints to display a label and a button next to one another. However, the UIImageView used as the button's background is making the intrinsic size of the button much too large.
I attempted to add a constraint that forces the height of the button to match the height of the label. But I just got a super tall label instead of a smaller button.
How do I set a constraint so that the button height is the same height as the label (and not vice-versa)
The button should keep the original aspect ratio of the image - its width should also match its own height (maybe this comes for free?)
The following works for this:
Set a width for the button in the visual layout: #"|-[titleLabel][refreshButton(==26)]"
Add a constraint such that the height of the button is equal to its own (now explicit) width:
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:refreshButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:refreshButton
attribute:NSLayoutAttributeWidth
multiplier:1.0f
constant:0.0f];
I would still prefer a solution that uses the label's height, instead of a fixed value.

Resources