Autolayout in code ? height issue? - ios

I have Two View say view1 and view2.
- view2 should be at 2 pixel distance from view1 (vertically) and
- Height of view2 should be such that bottom of view2 must be same as bottom of viewcontroller.
How to specify the constraint for this in code ?

Since I don't know what you already have in your view hierarchy I've set up a simple example. Look into this bit of code. It creates two new UIViews and position them using constraints.
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view1 = [UIView new];
UIView *view2 = [UIView new];
view1.backgroundColor = [UIColor redColor];
view2.backgroundColor = [UIColor blueColor];
[self.view addSubview:view1];
[self.view addSubview:view2];
[view1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[view2 setTranslatesAutoresizingMaskIntoConstraints:NO];
NSDictionary *views = NSDictionaryOfVariableBindings(view1, view2);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(100)-[view1(200)]-(2)-[view2]|" options:0 metrics:0 views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|[view1]|" options:0 metrics:0 views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|[view2]|" options:0 metrics:0 views:views]];
}
Here's the result:
Code is not that hard to understand. + constraintsWithVisualFormat: method creates an array of NSLayoutConstraints that you add to the superview of your custom views. Look here for more on visual format language. It's very effective at simple layout and saves a bunch of time compared to creating constraints one by one.
If you reeeaaally want to create constraints using constraintWithItem: method, here's your code:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:100]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:view2 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view1 attribute:NSLayoutAttributeBottom multiplier:1 constant:2]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:view2 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:200]];
It results in the same constraints, but takes up twice the space and is harder to read.So I strongly recommend you to use visual format instead. You should only use constraintWithItem: for more complicated layout which visual format can't always handle.

Related

Horizontal stacking in scrollview using autolayout

What's the best way to make sure that child views in a UIScrollView are stacked horizontally, one after the other, using autolayout? The number of child views will vary, so I can't use IB, but have to do it programatically. I understand how layout constraints work, but what's the best way to solve it? Loop all child views and update the constraints for each view everytime the number of child views are updated? If so, is there an easy solution to refer to the previous sibling in a layout constraint, or do I have have to keep a reference to the previous sibling?
I wrote the following method for an app. Might not be the prettiest but it gets the job done. It takes the views as an array which solves the problem of having a reference to the previous view. It also uses transparent spacer views to space them evenly but you can easily take those out.
+(void)spaceViews:(NSArray*)views evenlyInContainer:(UIView*)container {
UIView* lastSpacer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
lastSpacer.translatesAutoresizingMaskIntoConstraints = NO;
[lastSpacer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[lastSpacer(10)]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(lastSpacer)]];
[container addSubview:lastSpacer];
[container addConstraint:[NSLayoutConstraint constraintWithItem:container attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:lastSpacer attribute:NSLayoutAttributeLeading multiplier:1.f constant:0]];
for (int i = 0; i < [views count]; i++) {
[container addSubview:views[i]];
[container addConstraint:[NSLayoutConstraint constraintWithItem:lastSpacer attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:views[i] attribute:NSLayoutAttributeLeading multiplier:1.f constant:0]];
UIView* spacerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
[spacerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[spacerView(10)]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(spacerView)]];
spacerView.translatesAutoresizingMaskIntoConstraints = NO;
[spacerView setBackgroundColor:[UIColor blueColor]];
[container addSubview:spacerView];
[container addConstraint:[NSLayoutConstraint constraintWithItem:spacerView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:views[i] attribute:NSLayoutAttributeTrailing multiplier:1.f constant:0]];
[container addConstraint:[NSLayoutConstraint constraintWithItem:spacerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:container attribute:NSLayoutAttributeCenterY multiplier:1.f constant:0]];
[container addConstraint:[NSLayoutConstraint constraintWithItem:views[i] attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:container attribute:NSLayoutAttributeCenterY multiplier:1.f constant:0]];
if (lastSpacer) {
[container addConstraint:[NSLayoutConstraint constraintWithItem:spacerView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:lastSpacer attribute:NSLayoutAttributeWidth multiplier:1.f constant:0]];
}
lastSpacer = spacerView;
}
[container addConstraint:[NSLayoutConstraint constraintWithItem:lastSpacer attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:container attribute:NSLayoutAttributeTrailing multiplier:1.f constant:0]];
}

How to set equal widths for UIViews using auto-layouts "Constraint with item format"

In my application I have inserted UIViews on view controller. My main requirement is that I want to set equal widths for both UIViews using auto-layouts "Constraint with item format".
For this I have written some code but I did not get equal widths. What did I do here wrong?
I want get result like below image (i.e need to set equal widths for both UIViews).
My code:
#import "ViewController8.h"
#interface ViewController8 ()
{
UIView * myView1;
UIView * myView2;
}
#end
#implementation ViewController8
- (void)viewDidLoad {
[super viewDidLoad];
myView1 = [[UIView alloc] init];
myView1.backgroundColor = [UIColor lightGrayColor];
myView1.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:myView1];
myView2 = [[UIView alloc] init];
myView2.backgroundColor = [UIColor redColor];
myView2.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:myView2];
[self operation2];
}
-(void)operation2
{
//Applying autolayouts for myview2
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView2
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1.0
constant:50]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView2
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:-10]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView2
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-30]];
//Applying autolayouts for myview1
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:10]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1.0
constant:50]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:myView2
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:-30]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-30]];
}
Equal width constraint is not there in your posted code. Try adding this
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:200]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView2
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:myView1
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0]];
It's enough to add the equal-width constraint
[NSLayoutConstraint constraintWithItem:myView1
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:myView2
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0];
You must not define the width of the two views explicitly using constraints because view1 is pinned to the leading edge of the superview, view2 is pinned to the trailing edge of the superview and the trailing edge of view1 is pinned to the leading edge of view2. Hence, the constraint system is fully determined after adding the above equal-width constraint.
This is what adding the constraint will lead to:
Contemporary solution is using NSLayoutAnchor
myView1.widthAnchor.constraint(equalTo: myView2.widthAnchor)
don't forget to activate this using isActive = true, or via NSLayoutConstraint.activate().

How to horizontally center UITextView content in iOS, but not using Align Center?

I want to achieve something very specific. It is hard to describe in words so here are some mockups..
Current stage: I have a UITextView which has autolayout constraints set to be as wide as the parent container.
What I want to achieve: I would like to horizontally center the contents in the UITextView, so that they appear in center but are still left aligned
Most solutions rely on TextAlignCenter option to center the text horizontally, however this is not something that I want as it will appear as such instead:
Any way to achieve this?
I've tried the below:
textview.sizeToFit() seems to adjust the height but not the width
textview.contentOffset does not seem to work
Removing the constraints in autolayout and use Editor > Fix all in scope seems to work on UIButtons but not UITextView..
The reason I want to do this is although it is not noticable on iPhones, on iPads if the text are short they appear all the way to the left, which is very far from my other interactable buttons in my app.
It looks like you are probably using Swift, but that's fine, here's the code for Objective-C, just convert it.
UITextView * _descriptionText = [UITextView new];
[_descriptionText setDelegate:self];
[_descriptionText setBackgroundColor:[UIColor whiteColor];
[_descriptionText setTranslatesAutoresizingMaskIntoConstraints:false];
[_descriptionText setTextColor:[UIColor lightGrayColor]];
[_descriptionText setTextAlignment:NSTextAlignmentLeft];
then, add this textview to a UIView
[sss addSubview:_descriptionText];
Here's the code for the UIView:
UIView * sss = [UIView new];
[sss setTranslatesAutoresizingMaskIntoConstraints:FALSE];
[self addSubview:sss];
Add constraints to the UIView to center the UITextView and to constrain it's bounds by a certain Width on the left and right sides:
[sss addConstraint:[NSLayoutConstraint constraintWithItem:descriptionText attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeHeight multiplier:1.0f constant:SOME_HEIGHT_NUMBER_YOU_CHOOSE]];
[sss addConstraint:[NSLayoutConstraint constraintWithItem:descriptionText attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeHeight multiplier:1.0f constant:SOME_RIGHT_MARGIN_NUMBER_YOU_CHOOSE]];
[sss addConstraint:[NSLayoutConstraint constraintWithItem:descriptionText attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeLeft multiplier:1.0f constant:SOME_LEFT_MARGIN_NUMBER_YOU_CHOOSE]];
or choose a width for the UITextView like this with a CenterX constraint:
[sss addConstraint:[NSLayoutConstraint constraintWithItem:descriptionText attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:SOME_WIDTH_NUMBER_YOU_CHOOSE]];
[sss addConstraint:[NSLayoutConstraint constraintWithItem:descriptionText attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0]];
And finally, add a CenterY constraint:
[sss addConstraint:[NSLayoutConstraint constraintWithItem:descriptionText attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0]];
Lastly, constrain the UIView "sss" to it's super view "self" or whatever it's superview is:
NSDictionary * views = NSDictionaryOfVariableBindings(sss);
NSDictionary * metrics = #{#"bh" : #30, #"bsh" : #40, ... etc, etc,};
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[sss]|" options:0 metrics:metrics views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-bh-[sss]" options:0 metrics:metrics views:views]];
and then, profit!
Formatted code with subclass UIView
ExampleView.m
#implementation ExampleView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
UIView * sss = [UIView new];
[sss setTranslatesAutoresizingMaskIntoConstraints:false];
[self addSubview:sss];
UITextView * _descriptionText = [UITextView new];
[_descriptionText setBackgroundColor:[UIColor whiteColor]];
[_descriptionText setTranslatesAutoresizingMaskIntoConstraints:false];
[_descriptionText setTextColor:[UIColor lightGrayColor]];
[_descriptionText setTextAlignment:NSTextAlignmentLeft];
[sss addSubview:_descriptionText];
//do these three constraints
[sss addConstraint:[NSLayoutConstraint constraintWithItem:_descriptionText attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeHeight multiplier:1.0f constant:SOME_HEIGHT_NUMBER_YOU_CHOOSE]];
[sss addConstraint:[NSLayoutConstraint constraintWithItem:_descriptionText attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeRight multiplier:1.0f constant:SOME_RIGHT_MARGIN_NUMBER_YOU_CHOOSE]];
[sss addConstraint:[NSLayoutConstraint constraintWithItem:_descriptionText attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeLeft multiplier:1.0f constant:SOME_LEFT_MARGIN_NUMBER_YOU_CHOOSE]];
//or do these three constraints, but don't do all 6 constraints between these three and the three above
[sss addConstraint:[NSLayoutConstraint constraintWithItem:_descriptionText attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:SOME_WIDTH_NUMBER_YOU_CHOOSE]];
[sss addConstraint:[NSLayoutConstraint constraintWithItem:_descriptionText attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0]];
[sss addConstraint:[NSLayoutConstraint constraintWithItem:_descriptionText attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:sss attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0]];
NSDictionary * views = NSDictionaryOfVariableBindings(sss);
NSDictionary * metrics = #{#"bh" : #30, #"bsh" : #40};
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[sss]|" options:0 metrics:metrics views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-bh-[sss]" options:0 metrics:metrics views:views]];
// this: V:|-bh-[sss] SHOULD WORK, BUT IT MIGHT REQUIRE YOU TO DO THIS: V:|-bh-[sss(HEIGHT_OF_THE_TEXT_VIEW_THAT_YOU_CHOOSE)]
}
return self;
}
#end
ExampleView.h
#import <UIKit/UIKit.h>
#interface NSHMessagesView : UIView
#end
I think you can subclass UITextView or set contentInset. beacause it's subclass scrollView, so i guess set contentInset can achevie the goal.

All images of UIScrollView are getting placed in the beginning

I am new to iOS programming. I want to generate all the controls using coding and then apply constraints to achieve autosize feature. I had achieved almost my requirement except for one problem and that is all images of my UIScrollView are getting placed at very beginning and rest of the UIScrollView stays empty. I think I am having some sort of problem with my constraints and currently I am not able to resolve it.
This is my code
self.bgView.image = [UIImage imageNamed:#"bg.png"];
NSDictionary *viewDictionary = #{#"bgImage":self.bgView,#"scrollView":self.scrollView};
NSDictionary *position = #{#"vSpacing":#0,#"hSpacing":#0};
//here I had specified the size of the background image corresponding to the view
NSArray *constraint_POS_H = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-hSpacing-[bgImage]-hSpacing-|" options:0 metrics:position views:viewDictionary];
NSArray *constraint_POS_V = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-vSpacing-[bgImage]-vSpacing-|" options:0 metrics:position views:viewDictionary];
[self.view addConstraints:constraint_POS_H];
[self.view addConstraints:constraint_POS_V];
//here I am specifying the size of scroll view
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:self.scrollView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:self.bgView
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:self.scrollView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.bgView
attribute:NSLayoutAttributeHeight
multiplier:0.5
constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:self.scrollView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.bgView
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:self.scrollView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.bgView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
//self.view.autoresizesSubviews = YES;
self.scrollView.pagingEnabled = YES;
NSInteger numberOfViews = photoArray.count;
for (int i=0; i < numberOfViews; i++) {
CGFloat myOrigin = i * self.view.frame.size.width;
NSLog(#"self.view.frame.size.width : %f",self.view.frame.size.width);
UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(myOrigin, 0, self.view.frame.size.width, self.scrollView.frame.size.height)];
[myView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:myView];
//here I am specifying the size of uiview
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:myView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:self.scrollView
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:myView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.scrollView
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0.0]];
//here I am specifying the position of uiview
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:myView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.scrollView
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:myView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.scrollView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
UIImageView *photos = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, myView.frame.size.width, self.scrollView.frame.size.height)];
//self.photos = [UIImageView new];
[photos setTranslatesAutoresizingMaskIntoConstraints:NO];
photos.image = [photoArray objectAtIndex:i];
[myView addSubview:photos];
//here I am specifying the size of image view within scroll view
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:photos
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationLessThanOrEqual
toItem:myView
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:photos
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.scrollView
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0.0]];
//here I am specifying the position of the image view
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:photos
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.scrollView
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:photos
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:myView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
self.scrollView.delegate = self;
[self.scrollView addSubview:myView];
NSLog(#"self.myView.frame.size.width : %f",myView.frame.size.width);
}
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews,
self.scrollView.frame.size.height);
CGPoint scrollPoint = CGPointMake(0, 0);
[self.scrollView setContentOffset:scrollPoint animated:YES];
[self.view addSubview:self.scrollView];
you can easily solve it by just using reset to suggested constraints in storyboard.First select viewController and then press right bottom menu and select reset to suggested constraints in All views tab
This worked for me.

Error in programmatically Auto-layout vertically ios

I am creating view programmatically, In it there is two sub views, I have set height and width constraint for that,
what I want is like this,
UIView (variable height)
[10px gap]
UIView (fix height 40)
but I got:
My code is:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *button1, *button2 ;
button1=[UIView new];
button2=[UIView new];
button1.backgroundColor=[UIColor redColor];
button2.backgroundColor=[UIColor yellowColor];
button1.translatesAutoresizingMaskIntoConstraints=button2.translatesAutoresizingMaskIntoConstraints=NO;
[self.view addSubview:button1];
[self.view addSubview:button2];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(button1,button2);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[button1]-|"
options:0
metrics:nil
views:viewsDictionary];
[self.view addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[button1]-10-[button2]-|"
options: NSLayoutFormatAlignAllLeft
metrics:nil
views:viewsDictionary];
[self.view addConstraints:constraints];
}
Edit
Second Try
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *button1, *button2 ;
button1=[UIView new];
button2=[UIView new];
button1.backgroundColor=[UIColor redColor];
button2.backgroundColor=[UIColor yellowColor];
button1.translatesAutoresizingMaskIntoConstraints=button2.translatesAutoresizingMaskIntoConstraints=NO;
[self.view addSubview:button1];
[self.view addSubview:button2];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button1
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:25.0]];
// [self.view addConstraint:[NSLayoutConstraint constraintWithItem:button1
// attribute:NSLayoutAttributeWidth
// relatedBy:NSLayoutRelationEqual
// toItem:nil
// attribute:NSLayoutAttributeNotAnAttribute
// multiplier:1.0
// constant:100]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button1
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:-25.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button1
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:30]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button1
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:button2
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-30.0]];
//// Yellow
/// Left
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button2
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:25.0]];
//Right
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button2
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:-50.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button2
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:button1
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:30]];
// [self.view addConstraint:[NSLayoutConstraint constraintWithItem:button2
// attribute:NSLayoutAttributeBottom
// relatedBy:NSLayoutRelationEqual
// toItem:self.view
// attribute:NSLayoutAttributeBottom
// multiplier:1.0
// constant:-30.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button2
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:100]];
}
In this I got:
Regular views don't have any intrinsic size, and you've given the system no hints about how big the views should be, so button 1 gets laid out first with at least 10 points to spare, and view 2 ends up being 0 points high and 0 points wide.
To correct this, make sure that you give both views some horizontal rules, not just one of the views. Secondly, make sure you give the system some idea about height. If you want the views to be equal sizes, you need to tell the system that. Add another horizontal constraint for button 2:
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[button2]-|" options:0 metrics:0 views:viewsDictionary];
[[self view] addConstraints:constraints];
Then add a height constraint for the view, in this case, adjust your vertical constraints to make the views equal heights by adding the (==button1) size information:
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[button1]-10-[button2(==button1)]-|"
options:0
metrics:nil
views:viewsDictionary];
Now you should see two views, red on top, yellow on bottom, that take up an equal amount of vertical space, have 10p space between and stretch to 20 points of each side of the container view.
To create these same constraints manually (which I don't recommend), you would do something like this:
UIView* view = [self view]; // for brevity
NSMutableArray* manualConstraints = [NSMutableArray array];
NSLayoutConstraint* b1_top = [NSLayoutConstraint constraintWithItem:button1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTop multiplier:1 constant:20];
[manualConstraints addObject:b1_top];
NSLayoutConstraint* b1_left = [NSLayoutConstraint constraintWithItem:button1 attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeading multiplier:1 constant:20];
[manualConstraints addObject:b1_left];
NSLayoutConstraint* b1_right = [NSLayoutConstraint constraintWithItem:button1 attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTrailing multiplier:1 constant:-20];
[manualConstraints addObject:b1_right];
NSLayoutConstraint* b1_bottom = [NSLayoutConstraint constraintWithItem:button1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:button2 attribute:NSLayoutAttributeTop multiplier:1 constant:-10];
[manualConstraints addObject:b1_bottom];
NSLayoutConstraint* b2_left = [NSLayoutConstraint constraintWithItem:button2 attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeading multiplier:1 constant:20];
[manualConstraints addObject:b2_left];
NSLayoutConstraint* b2_right = [NSLayoutConstraint constraintWithItem:button2 attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTrailing multiplier:1 constant:-20];
[manualConstraints addObject:b2_right];
NSLayoutConstraint* b2_bottom = [NSLayoutConstraint constraintWithItem:button2 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeBottom multiplier:1 constant:-20];
[manualConstraints addObject:b2_bottom];
NSLayoutConstraint* b2_height = [NSLayoutConstraint constraintWithItem:button2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:40];
[manualConstraints addObject:b2_height];
// Add all constraints
[view addConstraints:manualConstraints];

Resources