I have a UIView created from a xib file. Inside that UIView there is a UIButton with a text that may be longer or shorter depending on the language.
What I want is to resize the parent UIView to fit the width of the UIButton. How can I do it with AutoLayout, or programmatically?
Thanks,
add leading, trailing, top and bottom constraint of button
add width constraint of view and connect to viewWidthConstraint.
calculate width of button for language and set constant of viewWidthConstraint.
View and button will resize
#property (nonatomic, weak) IBOutlet NSLayoutConstraints *viewWidthConstraint;
- (void)viewDidLoad {
super.viewDidLoad();
self.viewWidthConstraint.constant = [self buttonWidth];
}
- (CGFloat)buttonWidth {
return 100.f; (calculate width of button)
}
Related
Here is my structure of views for this
-ViewController
-UIView
-UIScrollView
-UIView * customview
Data comes form web Serivce. automatically increase the UIScrollView Height and subview Height.
I am fixing autolayouts to UIScrollView and UIView.
In customview UILables and UITableView.
You need to take the Outlet of your customeview height constrains.
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewHeight;
bind viewHeight with your customeview height constrains and set the constant property of your outlet
self.viewHeight.constant = 2000; //Your subview Height
in define image you can see the your subview height constrains and bind outlet with this constrains after it height will change dynamically as per your .constant value.
I have a UILabel for item description amongst other views, all laid out using constraints in Interface Builder - you can see all relevant constraints in the image below. The number of lines is also set to 0.
I haven't set the height constraint because I want the UILabel to resize based on the text it contains. Instead, what happens is right after
[self.view layoutIfNeeded];
is called, the height of the UILabel gets set to 0. Even if I don't set other text to the UILabel, it has a default value of Item description set in Interface Builder.
The item title label above is set the same way, but that one doesn't get squashed to 0, so I'm a bit confused.
Anyone had any experience with such behaviour?
I managed to solve it by setting the UILabel's vertical compression resistance priority to 1000 (default 750) in Interface Builder.
Since my views are embedded in another view, and the parent view's bottom is dependent on the bottom of the lowest child view, I only speculate that the UILabel without a height constraint was getting squeezed in the process of laying out the views. Probably playing with priorities of other constraints somewhere down the chain would have yielded the same result, but I wasn't able to do it successfully. The solution above, however, worked, which is good enough in my case.
Hope this helps someone.
Set 3 constraint
1.Leading space to superview
2.Trailing space to superview
3.Top space to superview
then
#property (nonatomic, strong) IBOutlet UILabel *lbl;
- (void) viewDidLoad{
[self.lbl sizeToFit];
}
ctrl drag from the label to itself > select height > set the constant of the height to 0 and change equal (==) to greater than or equeal (>=)
I think you need to set 5 constraints on your label :
Leading space to superview
Trailing space to superview
Vertical space to "Item"
Vertical space to "Name"
Height
Then add an IBOutlet in your controller on the constraint height (let's say labelHeight).
So in your viewDidLoad you will be able to set this constraint value:
#property (weak, nonatomic) IBOutlet UILabel *label;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelHeight;
- (void) viewDidLoad{
[self.label sizeToFit];
labelHeight.constant = self.label.frame.size.height;
}
AutoLayout in this UIViewController can't satisfy all the constraints you have set, therefore it dismiss those on your UILabel, resulting in a compressed state. You should have a look at the other constraints in your UIViewController, and set the priority of the height contraint to a higher number.
I am trying to make a vertical progress bar in iOS that can be placed as a UIView in interface builder, and given a progress bar view class. Here are my class files:
ProgressBar.h:
#interface ProgressBar : UIView
#property (nonatomic, retain) IBOutlet UIView *barView
-(void)setBarValue:(float)value;
#end
ProgressBar.m:
-(id)initWithCoder:(NSCoder *)aDecoder {
id s = [super initWithCoder:aDecoder];
if (s) {
self.backgroundColor = [UIColor clearColor];
}
return s;
}
-(void)setBarValue:(float)val {
[self.barView setBackgroudnColor:TURQUOISE];
CGRect frame = self.barView.frame;
frame.size.height = self.barview.frame.size.height * val;
[self.barView setFrame:frame];
}
The only constraint I have on the 'barView' inside the ProgressBar element is 'align bottom edges'. The setFrame method never seems to update the bar, and even at full height, the inner self.barView isn't the same height as the ProgressBar view. The properties are all correctly linked in the Storyboard.
Any ideas?
The key issue is that, if using autolayout, you should add your constraints for this subview in IB, too. (I assume you already added constraints for the ProgressView.) And you should not change the frame of barView, but rather change its constraints and then call setNeedsLayout. The easiest way will be to add leading/trailing/top constraints of zero and then create a final height constraint. You can then add an IBOutlet for that height constraint. You can then programmatically set the constant of that constraint (and if you're going to use a multiplicative factor, it should be the product of this factor and the overall progress view, not a factor of the bar, itself), and then call setNeedsLayout.
I am using autolayout. In xib i have a scrollview as a parent view. Added one view as a subview. For that subview i have added four child elements. Three are views(say view1,view2,view3) and one is label which is having multiline text.
I am using the below code to change the height of the view
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *view1Height;
self.view1Height.constant = 200;
In this case there is no issues with content size the view2 and view3 frames are adjusted automatically.
But while coming to multiline label I am using the below code for setting label text
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *textLabelHeight;
self.textLabelHeight.constant = expectedLabelSize.height;
But here I am facing issue with scroll content size. Unable to view the entire text. Similarly I want to place one more view below the label how to set constraints for it.
I am struggling with maybe a bit of a rookie issue. I have a UIView within which I display some price. I want the UIView to be of a dynamic width according to the price, if its 1 Euro, then it will be e.g. 20pt, if its 2300 Euro, then it will be like 50pt in width.
I was trying to use the storyboard's constraints but without luck. Is it possible to do it within storyboard or do I have to calculate the width of UILabel and then set the width of UIView programmatically?
Thank you in advance.
Yes, you can do this in the storyboard. Add a label to your view and pin it to the left and right edge (top and bottom if you want also). Give the view constraints to its superview in the x and y directions, but do not give it a width constraint (it will need a height constraint if you didn't pin the top and bottom of the label to it). The view should then expand with the label depending on its content.
In general, auto layout is performed in a top-down fashion. In other words, a parent view layout is performed first, and then any child view layouts are performed. So asking the system to size the parent based on the child is a bit like swimming upstream, harder to do, but still possible with some work.
One solution is to use the intrinsic size of a view.
For example, a UILabel has an intrinsic size based on the text in the label. If a UILabel has a leading constraint and a top constraint, but no other constraints, then its width and height are determined by its intrinsic size.
You can do the same thing with a custom view class that encloses a UILabel. By setting the intrinsic size of the custom view class based on the intrinsic size of the UILabel, you get a view that automatically resizes based on the text in the label.
Here's what the code looks like for the custom class. The .h file defines a single property text. The .m file has an IBOutlet to the child label. Setting and getting the text property simply sets or gets the text from the label. But there's one very important twist, setting the text invalidates the intrinsic size of the parent. That's what makes the system adjust the size of the parent view. In the sample code below the parent is sized to have an 8 pixel margin all around the UILabel.
SurroundView.h
#interface SurroundView : UIView
#property (strong, nonatomic) NSString *text;
#end
SurroundView.m
#interface SurroundView()
#property (weak, nonatomic) IBOutlet UILabel *childLabel;
#end
#implementation SurroundView
- (void)setText:(NSString *)text
{
self.childLabel.text = text;
[self invalidateIntrinsicContentSize];
}
- (NSString *)text
{
return( self.childLabel.text );
}
- (CGSize)intrinsicContentSize
{
CGSize size = self.childLabel.intrinsicContentSize;
size.height += 16;
size.width += 16;
return( size );
}
#end
Creating the IBOutlet to the childLabel can be a little tricky, so here's the procedure
drag out a UIView into the storyboard
use the Identity inspector to change the class to SurroundView
drag out a UILabel and add it as a subview of the SurroundView
select the label, and open the assistant editor
show SurroundView.m in the assistant
drag from the open circle to the label as shown below
All that's left is to get the constraints right. The constraints for the label should look like this
The constraints for the SurroundView should be as shown below. The key point is that the Intrinsic Size should be set to Placeholder to avoid the warnings about missing constraints.
Place the label inside the view and pin its TOP , BOTTOM , TRAILING and LEADING edges to the labels superview. Note that you do not specify the width constraint. Now add a height and width constraint to the view. Make an outlet to the width constraint and when the price changes set the view's width constraint's constant to your desired value. Since the label is pinned to the view it will expand too.