I have added some text fields through story board vertically.Below them i want to add more text fields programatically but it is always adding only one text field.
Below is the code used
int i;
self.main_view.translatesAutoresizingMaskIntoConstraints = NO;
self.scroll_view.translatesAutoresizingMaskIntoConstraints = NO;
for (i=0; i<[arr_customEdtTxt count]; i++)
{
JVFloatLabeledTextField *tf = [[JVFloatLabeledTextField alloc] initWithFrame:CGRectMake(25, y, 270, 27)];
tf.textColor = [UIColor blackColor];
tf.font = [UIFont fontWithName:#"Helvetica" size:14];
CustomEditText *custom=[arr_customEdtTxt objectAtIndex:i];
tf.placeholder=custom.field_name;
tf.textAlignment=NSTextAlignmentLeft;
previousTextfield=tf;
//add bottom border
[self addBorder:tf];
tf.translatesAutoresizingMaskIntoConstraints = NO;
[self.main_view addSubview:tf];
y=y+27;
[self.main_view addConstraint:[NSLayoutConstraint constraintWithItem:tf attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.main_view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0] ];
[self.main_view addConstraint:[ NSLayoutConstraint constraintWithItem:tf
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:27.0]];
[self.main_view addConstraint:[ NSLayoutConstraint constraintWithItem:tf
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.txt_email
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0]];
if(i==0)
{
[self.main_view addConstraint:[NSLayoutConstraint constraintWithItem:tf attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.txt_exprience attribute:NSLayoutAttributeBottom multiplier:1 constant:15.0f]];
}
else
{
[self.main_view addConstraint:[NSLayoutConstraint constraintWithItem:tf attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:previousTextfield attribute:NSLayoutAttributeBottom multiplier:1 constant:15.0f]];
}
[arr_tf addObject:tf];
}
[self.main_view layoutIfNeeded];
[self setDatatoFields];
I am getting constraint error i want to add more text fields below the current text fields.Please tell how can i add more and more text fileds below
It looks like previousTextfield and tf refer to the same textfield in this line:
[self.main_view addConstraint:[NSLayoutConstraint constraintWithItem:tf attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:previousTextfield attribute:NSLayoutAttributeBottom multiplier:1 constant:15.0f]];
Also I noticed that at the end you add the textField to arr_tf but you also have arr_customEdtTxt depending on which one is your array of textFields you should change previousTextfield = tf with:
if(i > 0){
//Change arr_tf for arr_customEdtTxt if that is your array
previousTextfield = [arr_tf objectAtIndex:i-1];
}
Related
I am actually trying to have UIView which houses UIImageView and UILabel (side by side). There are multiple such pairs present. I need these pairs one below the other. But after the second pair, the overlapping starts in spite of giving vertical contraints. The code below is actually resulting in Views getting overlapped (third and fourth getting on to second) I am unable to know exactly what is going wrong. Appreciate if somebody could point out this
UIView *bottomCaseStudiesLyt = [[UIView alloc]init];
bottomCaseStudiesLyt.translatesAutoresizingMaskIntoConstraints = NO;
[contentView addSubview:bottomCaseStudiesLyt];
NSLayoutConstraint* bottomCaseStudiesleftConstraint = [NSLayoutConstraint constraintWithItem:bottomCaseStudiesLyt attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:contentView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:10.0f];
[contentView addConstraint:bottomCaseStudiesleftConstraint];
NSLayoutConstraint* bottomCaseStudiesTopConstraint = [NSLayoutConstraint constraintWithItem:bottomCaseStudiesLyt attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:details3View attribute:NSLayoutAttributeBottom multiplier:1.0f constant:10.0f];
[contentView addConstraint:bottomCaseStudiesTopConstraint];
NSLayoutConstraint* bottomCaseStudiesRightConstraint = [NSLayoutConstraint constraintWithItem:bottomCaseStudiesLyt attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:contentView attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:-10.0f];
[contentView addConstraint:bottomCaseStudiesRightConstraint];
NSLayoutConstraint* bottomCaseStudiesBottomConstraint = [NSLayoutConstraint constraintWithItem:bottomCaseStudiesLyt attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:contentView attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f];
[contentView addConstraint:bottomCaseStudiesBottomConstraint];
//NSArray *bottomCaseStudiesVConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[headingDetailsView]-[details2View]-[details3View]-[bottomCaseStudiesLyt]|" options:0 metrics:nil views:#{#"headingDetailsView": headingDetailsView,#"details2View": details2View,#"details3View": details3View,#"bottomCaseStudiesLyt": bottomCaseStudiesLyt}];
//[contentView addConstraints:bottomCaseStudiesVConstraints];
UIView *firstView = [[UIView alloc]init];
[firstView setTranslatesAutoresizingMaskIntoConstraints:NO];
[bottomCaseStudiesLyt addSubview: firstView];
[self addImageAndDetails:bottomCaseStudiesLyt previousview:nil whichimage:#"ic_action_easy" whattext:#"Rediculously easy. Takes less than 30 seconds to build a room and go live" mynewview:firstView];
UIView *secondView = [[UIView alloc]init];
[secondView setTranslatesAutoresizingMaskIntoConstraints:NO];
[bottomCaseStudiesLyt addSubview: secondView];
[self addImageAndDetails:bottomCaseStudiesLyt previousview:firstView whichimage:#"ic_action_amaze" whattext:#"Engage members with great content, services, offers, polls, notification, quiz and more" mynewview:secondView];
UIView *thirdView = [[UIView alloc]init];
[thirdView setTranslatesAutoresizingMaskIntoConstraints:NO];
[bottomCaseStudiesLyt addSubview: thirdView];
[self addImageAndDetails:bottomCaseStudiesLyt previousview:secondView whichimage:#"ic_action_subscribers" whattext:#"Members ? No limit! There is a room for all. Go ahead and promote your room." mynewview:thirdView];
UIView *fourthView = [[UIView alloc]init];
[fourthView setTranslatesAutoresizingMaskIntoConstraints:NO];
[bottomCaseStudiesLyt addSubview: fourthView];
[self addImageAndDetails:bottomCaseStudiesLyt previousview:thirdView whichimage:#"ic_action_crossplatform" whattext:#"Your room can be accessed from any platform or device." mynewview:fourthView];
NSArray *bottomViewVConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[firsView]-[secondView]-[thirdView]-[fourthView]|" options:0 metrics:nil views:#{#"firsView": firstView,#"secondView": secondView,#"thirdView": thirdView,#"fourthView": fourthView}];
[bottomCaseStudiesLyt addConstraints:bottomViewVConstraints];
// GetStarted button
self->m_ObjGetStartedBut = [[UIButton alloc]init];
[self->m_ObjGetStartedBut setTitle: [NSString stringWithFormat:#"Get Started"] forState:UIControlStateNormal];
self->m_ObjGetStartedBut.backgroundColor = [UIColor redColor];
[self->m_ObjGetStartedBut setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
self->m_ObjGetStartedBut.translatesAutoresizingMaskIntoConstraints = NO;
self->m_ObjGetStartedBut.layer.cornerRadius = 10;
self->m_ObjGetStartedBut.clipsToBounds = YES;
[parentView addSubview:self->m_ObjGetStartedBut];
NSDictionary *myTopViews = #{
#"scrollView": self->myScrollView,
#"submitButton": self->m_ObjGetStartedBut
};
NSArray *myTopVConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[scrollView]-[submitButton(40)]|" options:0 metrics:nil views:myTopViews];
NSArray *myTopHConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[submitButton]-|" options:0 metrics:nil views:#{#"submitButton": self->m_ObjGetStartedBut}];
[parentView addConstraints:myTopVConstraints];
[parentView addConstraints:myTopHConstraints];
//[self->m_ObjGetStartedBut addTarget:self action:#selector(buttonIsReleased:) forControlEvents: UIControlEventTouchUpInside];
//[self->m_ObjGetStartedBut setTag:1];
}
-(UIView *)addImageAndDetails:(UIView *)localparentView previousview:(UIView *)prevView whichimage:(NSString *)imageName whattext:(NSString *)relatedText mynewview:(UIView *)itemView
{
NSLayoutConstraint* topViewleftConstraint = [NSLayoutConstraint constraintWithItem:itemView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:localparentView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:10.0f];
[localparentView addConstraint:topViewleftConstraint];
NSLayoutConstraint* topViewRightConstraint = [NSLayoutConstraint constraintWithItem:itemView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:localparentView attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:-10.0f];
[localparentView addConstraint:topViewRightConstraint];
NSLayoutConstraint* topViewTopConstraint = nil;
if(prevView == nil)
{
topViewTopConstraint = [NSLayoutConstraint constraintWithItem:itemView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:localparentView attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f];
[localparentView addConstraint:topViewTopConstraint];
}
else
{
//topViewTopConstraint = [NSLayoutConstraint constraintWithItem:itemView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:prevView attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f];
//[localparentView addConstraint:topViewTopConstraint];
}
UIImage *easyToCreateImg = [UIImage imageNamed:imageName];
UIImageView *easyToCreateImgView = [[UIImageView alloc] initWithImage:easyToCreateImg];
easyToCreateImgView.contentMode = UIViewContentModeScaleToFill;
easyToCreateImgView.translatesAutoresizingMaskIntoConstraints = NO;
easyToCreateImgView.clipsToBounds = YES;
[itemView addSubview:easyToCreateImgView];
NSLayoutConstraint* easyToCreateImgLeftConstraint = [NSLayoutConstraint constraintWithItem:easyToCreateImgView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:itemView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:2.0f];
[itemView addConstraint:easyToCreateImgLeftConstraint];
NSLayoutConstraint* easyToCreateImgTopConstraint = [NSLayoutConstraint constraintWithItem:easyToCreateImgView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:itemView attribute:NSLayoutAttributeTop multiplier:1.0f constant:2.0f];
[itemView addConstraint:easyToCreateImgTopConstraint];
NSLayoutConstraint *easyToCreateImgHtConstraint = [NSLayoutConstraint constraintWithItem:easyToCreateImgView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:80.0f];
[itemView addConstraint:easyToCreateImgHtConstraint];
NSLayoutConstraint *easyToCreateImgWidConstraint = [NSLayoutConstraint constraintWithItem:easyToCreateImgView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:80.0f];
[itemView addConstraint:easyToCreateImgWidConstraint];
UILabel* easyToCreateLblView = [[UILabel alloc]init];
[easyToCreateLblView setText:relatedText];
easyToCreateLblView.numberOfLines = 0;
UIFont *newHeadingViewLblFont = [UIFont fontWithName:#"Arial" size:13];
[easyToCreateLblView setFont:newHeadingViewLblFont];
[easyToCreateLblView setTextColor:[UIColor blackColor]];
easyToCreateLblView.translatesAutoresizingMaskIntoConstraints = NO;
[itemView addSubview:easyToCreateLblView];
NSLayoutConstraint* easyToCreateLblTopConstraint = [NSLayoutConstraint constraintWithItem:easyToCreateLblView attribute:NSLayoutAttributeCenterYWithinMargins relatedBy:NSLayoutRelationEqual toItem:easyToCreateImgView attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:2.0f];
[itemView addConstraint:easyToCreateLblTopConstraint];
NSLayoutConstraint* easyToCreateLblLeftConstraint = [NSLayoutConstraint constraintWithItem:easyToCreateLblView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:easyToCreateImgView attribute:NSLayoutAttributeRight multiplier:1.0f constant:2.0f];
[itemView addConstraint:easyToCreateLblLeftConstraint];
NSLayoutConstraint* easyToCreateLblRightConstraint = [NSLayoutConstraint constraintWithItem:easyToCreateLblView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:itemView attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:-10.0f];
[itemView addConstraint:easyToCreateLblRightConstraint];
return itemView;
}
I am not sure if my interpretation is right or wrong. What I observed is that when we give width and height constraints to the first view, this I think is not respected by the subsequent views that have been added. However, it does seem to respect the other constraints (top, bottom, leading, trailing). So when I started giving the same magnitude of width and height to the other subsequent views, then the arrangement came out as expected. Thoughts from the community are welcome.
I have a UIView in UITableViewCell. I am getting a array of names from service and I want to create a UILabel in a for loop inside a UIView which is in UITableViewCell according to the text width.
I have done this at my end but the problem is that I want to check if the label which is being created is having a width greater than the space remaining in its superview, then it should be created below the first line just like word wrapping of text in UILabel.
What I have done is, I have created a sample of code
-(void)addADaynamicViw
{
[self.vwContainer setTranslatesAutoresizingMaskIntoConstraints:false];
UILabel *lblPrevious;
int totalWidth;
for (int i=0; i<8; i++) {
UILabel *lbl=[[UILabel alloc]init];
//[lbl setFrame:CGRectMake(0, 0, 30, 50)];
[lbl setNumberOfLines:0];
[lbl setBackgroundColor:[UIColor greenColor]];
[lbl setTranslatesAutoresizingMaskIntoConstraints:false];
[lbl setText:[NSString stringWithFormat:#"Label Num %d",i]];
[self.vwContainer addSubview:lbl];
NSLayoutConstraint *top;
top=[NSLayoutConstraint constraintWithItem:lbl attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.vwContainer attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
NSLayoutConstraint *left;
if (lblPrevious) {
CGSize size = lblPrevious.intrinsicContentSize;
NSLog(#"intrinzik content size =%f",size.width);
left =[NSLayoutConstraint constraintWithItem:lbl attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationLessThanOrEqual toItem:lblPrevious attribute:NSLayoutAttributeLeft multiplier:1 constant:size.width+2];
}
else
{
left=[NSLayoutConstraint constraintWithItem:lbl attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationLessThanOrEqual toItem:self.vwContainer attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
}
NSLayoutConstraint *width=[NSLayoutConstraint constraintWithItem:lbl attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:10];
NSLayoutConstraint *height=[NSLayoutConstraint constraintWithItem:lbl attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:50];
NSLayoutConstraint *bottom=[NSLayoutConstraint constraintWithItem:lbl attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.vwContainer attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
NSLayoutConstraint *right=[NSLayoutConstraint constraintWithItem:lbl attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationLessThanOrEqual toItem:self.vwContainer attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0];
[self.vwContainer addConstraint:left];
[self.vwContainer addConstraint:bottom];
[self.vwContainer addConstraint:width];
[self.vwContainer addConstraint:top];
[self.vwContainer addConstraint:height];
[self.vwContainer addConstraint:right];
lblPrevious=lbl;
CGSize size = lblPrevious.intrinsicContentSize;
totalWidth+=size.width;
}
[self.vwContainer layoutIfNeeded];
[self.vwContainer updateConstraintsIfNeeded];
}
This line of code is creating the label programmatically after the end of previous label, but I want that if the label which is being created does not fit in its superview then it should increase the height of its superview and should start from 0 of its superview, but below the first label.
I am creating a custom searchbar with UITextfield. Searchbar should look like this:
But, In my case it is appearing like this:
What is the mistake I am doing in setting constraints for imageview on textfield
Code:
UITextField *searchBarTF=[[UITextField alloc]init];
[searchBarTF setBackgroundColor:[UIColor whiteColor]];
searchBarTF.layer.borderColor=[[UIColor darkGrayColor]CGColor];
searchBarTF.layer.borderWidth=7;
searchBarTF.layer.cornerRadius=5;
searchBarTF.returnKeyType=UIReturnKeySearch;
searchBarTF.attributedPlaceholder = [[NSAttributedString alloc] initWithString:#"Search by locations" attributes:#{NSForegroundColorAttributeName: [UIColor grayColor],NSFontAttributeName:[UIFont fontWithName:#"Helvetica" size:16]}];
searchBarTF.textAlignment=NSTextAlignmentCenter;
UIImageView *srchBariconImageView=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"srchBarIcon"]];
[srchBariconImageView setTranslatesAutoresizingMaskIntoConstraints:NO];
[searchBarTF addSubview:srchBariconImageView];
[searchBarTF addConstraint:[NSLayoutConstraint constraintWithItem:srchBariconImageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:searchBarTF attribute:NSLayoutAttributeLeading multiplier:1.0f constant:40]];
[searchBarTF addConstraint:[NSLayoutConstraint constraintWithItem:srchBariconImageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:searchBarTF attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:-(views.frame.size.width-80)]];
[searchBarTF addConstraint:[NSLayoutConstraint constraintWithItem:srchBariconImageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:40]];
//
// [searchBarTF addConstraint:[NSLayoutConstraint constraintWithItem:srchBariconImageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:40]];
[searchBarTF setTranslatesAutoresizingMaskIntoConstraints:NO];
// replace views with self.view.
[views addSubview:searchBarTF];
[views addConstraint:[NSLayoutConstraint constraintWithItem:searchBarTF attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:views attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0]];
[views addConstraint:[NSLayoutConstraint constraintWithItem:searchBarTF attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:60]];
// [views addConstraint:[NSLayoutConstraint constraintWithItem:searchBarTF attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:views attribute:NSLayoutAttributeTop multiplier:1.0 constant:-64]];
[views addConstraint:[NSLayoutConstraint constraintWithItem:searchBarTF attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:views attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0]];
[views addConstraint:[NSLayoutConstraint constraintWithItem:searchBarTF attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:views attribute:NSLayoutAttributeTop multiplier:1.0 constant:130]];
Subclass UITextField and overwrite these methods
- (void)awakeFromNib{
CGRect frame = self.leftView.frame;
frame.size.width = 30;
frame.size.height = 30;
self.leftView.frame = frame;
self.leftView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"underfloor_cross_blue.png"]];
}
- (CGRect)leftViewRectForBounds:(CGRect)bounds{
CGRect rect=CGRectMake(8, 8,50.0, 45);
[super leftViewRectForBounds:rect];
return rect ;
}
Note: change image and frame according to your need.
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.
Let say I have a N numbers of buttons..
//---listOfServicesToDisplay is DYNAMIC
NSMutableArray * arrayOfButtons = [NSMutableArray array];
for (int i=0; i<[listOfServicesToDisplay count]; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[arrayOfButtons addObject:button];
}
I want to add arrayOfButtons to my superView with a constraints of:
Center Y Alignment (Vertical)
Center X Alignment (Horizontal)
Leading and Trailing with 50 padding. H:|50-[BUTTON]50-|
Top and Bottom with padding 1
For the most Top/Bottom button its padding would be dynamic
If I do it on INTERFACE BUILDER It would be look like this..(hence that I NEED TO DO IT PROGRAMATICALLY)
I think this works, it sets up a wrapperView around the buttons, aligns the buttons inside this view and centers the wrapperView inside its superview.
UIView *buttonView = [UIView new];
[buttonView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:buttonView];
NSLayoutConstraint *horizontal = [NSLayoutConstraint constraintWithItem:buttonView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:buttonView.superview
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0];
NSLayoutConstraint *vertical = [NSLayoutConstraint constraintWithItem:buttonView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:buttonView.superview
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0];
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:buttonView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:buttonView.superview
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:-100];
// height will have to wait until we know what the buttons are up to
[buttonView.superview addConstraints:#[horizontal, vertical,width]];
CGFloat buttonHeight = 50;
CGFloat buttonSpace = 10;
NSInteger numberOfButtons = [buttons count]; // buttons = your array of buttons
for (NSInteger index = 0; index < numberOfButtons; index++) {
UIButton *button = [buttons objectAtIndex:index];
[buttonView addSubview:button];
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:buttonView
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:Nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:buttonHeight];
NSLayoutConstraint *horizontal = [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:buttonView
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0];
[buttonView addConstraints:#[ width, height, horizontal]];
// a bit clumsy here, due to the first button
if (index == 0) {
NSLayoutConstraint *vertical = [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:button.superview
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0];
[button.superview addConstraint:vertical];
} else{
UIButton *formerButton = [buttons objectAtIndex:index-1];
NSLayoutConstraint *vertical = [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:formerButton
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:buttonSpace];
[button.superview addConstraint:vertical];
}
}
UIButton *lastButton = [buttons lastObject];
CGFloat viewHeight = (buttonSpace + buttonHeight) * [buttons count];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:buttonView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:viewHeight];
[buttonView addConstraint:height];
Now, I haven't attempted to clean this up at all and you'd certainly don't want to have this all in one block, but the concept is sound and you should be able to achieve what you want. Personally I often use a separate class to handle constraints to avoid duplication of code.