Constraints to replace frame for UIButton - objective-c

I am trying to replace a set frame with constrains for a UIButton but my code keeps crashing, what am I doing wrong?
- (void)CreateButton {
self.Button = [[UIButton alloc] init];
//self.Button.frame = CGRectMake(30, 30, 100, 100);
[self.Button addConstraint:[NSLayoutConstraint constraintWithItem:MyScrollView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.myButton
attribute:NSLayoutAttributeTop
multiplier:2.0
constant:30]];
[self.myButton addConstraint:[NSLayoutConstraint constraintWithItem:MyScrollView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.myButton
attribute:NSLayoutAttributeHeight
multiplier:3.0
constant:50]];
[self.myButton setBackgroundColor:[UIColor orangeColor]];
[self.myButton setTitle:#"Press Me" forState:UIControlStateNormal];
[self.myButton setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[MyScrollView addSubview:self.myButton];

You should add the constraint to MyScrollView.

Related

UIImageView inside a scrollView with screen rotation

Its been 2 days working on this problem and i just can't figure it out.
I have a UIScrollView stretched in all my view and i am adding to it as subViews a random number of UIImageViews, and i am enabling paging so it will look like a gallery app.
My problem is when i rotate the screen, the images frames stays the same (this is probably because of the constraints) so i tried to give the images constraints and it worked they would rotate perfectly but then a problem appeared where the scroll view wont scroll anymore and the images are on top of each other ..
This is my code :
-(void)setupScrollView
{
for(int i = 0 ; i < [_arrayOfImages count] ; i++)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width*i, 0, self.view.frame.size.width, self.view.frame.size.height)];
[imageView setImage:[[_arrayOfImages objectAtIndex:i] getImageForImageView:imageView]];
[imageView setUserInteractionEnabled:YES];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_scrollView addSubview:imageView];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];
}
[_scrollView setContentSize:CGSizeMake(self.view.frame.size.width*[_arrayOfImages count], self.view.frame.size.height)];
}
Can anyone help me please ? thanks
You need to change the frame of UIScrollView and the UIImageViews in Autorotate delegate methods. After that you have to change the ContentSize of UIScrollView.
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientat‌​ion{}
//ios 7
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrient‌​ation{}
duration:(NSTimeInterval)duration -
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOri‌​entation{}
//ios 8
-(void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
if (size.width > size.height) {
// Positions for Landscape
} else {
// Positions for Portrait
}
}
I'am not really sure, because I need to see all application, but you can try following code
-(void)setupScrollView
{
for(int i = 0 ; i < [_arrayOfImages count] ; i++)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width*i, 0, self.view.frame.size.width, self.view.frame.size.height)];
[imageView setImage:[[_arrayOfImages objectAtIndex:i] getImageForImageView:imageView]];
[imageView setUserInteractionEnabled:YES];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_scrollView addSubview:imageView];
[imageViewArray addObject:imageView]
if (i == 0) {
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];
} else {
UIImageView * previousView = [imageViewArray objectAtIndex:i-1];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeLeading multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeTrailing multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];
}
}
[_scrollView setContentSize:CGSizeMake(self.view.frame.size.width*[_arrayOfImages count], self.view.frame.size.height)];
}
Also, you need to declare imageViewArray as NSMutableArray:
add to #interface:
NSMutableArray * imageViewArray;
and in viewDidLoad:
imageViewArray = [[NSMutableArray alloc] init];

How to vertically center two views & divide the width equally relative to the super view?

I'm trying to align two Buttons in a View (appearing in cyan). They get aligned vertically in the View. When i try to horizontally align them, their heights get changed. I want their widths should be the same according to the super view's width unlike smaller Next button. Can this be achieved only using VFL?
Here's the code:
[self prepareButton:saveButton label:#"SAVE"];
[buttonContainerView addConstraint:[NSLayoutConstraint constraintWithItem:saveButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:buttonContainerView
attribute:NSLayoutAttributeCenterY
multiplier:1.00f
constant:0]];
[saveButton layoutIfNeeded];
[self prepareButton:nextButton label:#"NEXT"];
[buttonContainerView addConstraint:[NSLayoutConstraint constraintWithItem:nextButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:buttonContainerView
attribute:NSLayoutAttributeCenterY
multiplier:1.00f
constant:0]];
[nextButton layoutIfNeeded];
[buttonContainerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[saveButton]-[nextButton]-|"
options:0
metrics:metrics
views:viewDictionary]];
[saveButton layoutIfNeeded];
[nextButton layoutIfNeeded];
-(void)prepareButton:(UIButton *)button
label:(NSString *) label
{
[buttonContainerView addSubview:button];
button.translatesAutoresizingMaskIntoConstraints = NO;
button.backgroundColor = [UIColor redColor];
button.layer.cornerRadius = 2.50f;
[button setTitle:label forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}
Solved the issue by setting equal height & assigning priority in VFL:
[buttonContainerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[saveButton]-[nextButton(==saveButton#1000)]-|"
options:0
metrics:metrics
views:viewDictionary]];

Adjusting subviews to keep their size using auto layout

I have a UIView that contains subviews that looks like this:
This view was originally designed with 320 width in mind. iPhone 5s and lower. However I am now adapting it to work with iPhone 6+
The issue I am facing is getting the subviews width to grow to accommodate the extra space on the left and right of their super view. I can only seem to get the centre views width to grow, however not the out views. What constraints would I need to apply or change in order to get all views to grow a little to accommodate the extra space on the sides?
Hi!
If you design your view in interface builder, you may try this:
1- set all views to specific width and height
2- the view at the corner add pin to the edge with static value.
3- the view in the middle add pin to top or bottom, and add align constraint to horizontal centre of superview
Not sure if this help, Just try to answer!
Here is a complete example of how to achieve this programmatically (with dummy views):
// Simple example demonstrating the below screenshots
// Create containers to hold each row of subviews
UIView *container1 = [UIView new];
container1.translatesAutoresizingMaskIntoConstraints = NO;
container1.backgroundColor = [UIColor redColor];
UIView *container2 = [UIView new];
container2.translatesAutoresizingMaskIntoConstraints = NO;
container2.backgroundColor = [UIColor orangeColor];
// Create the subviews
UIView *v1 = [UIView new];
v1.translatesAutoresizingMaskIntoConstraints = NO;
v1.backgroundColor = [UIColor grayColor];
UIView *v2 = [UIView new];
v2.translatesAutoresizingMaskIntoConstraints = NO;
v2.backgroundColor = [UIColor blackColor];
UIView *v3 = [UIView new];
v3.translatesAutoresizingMaskIntoConstraints = NO;
v3.backgroundColor = [UIColor greenColor];
UIView *v4 = [UIView new];
v4.translatesAutoresizingMaskIntoConstraints = NO;
v4.backgroundColor = [UIColor purpleColor];
UIView *v5 = [UIView new];
v5.translatesAutoresizingMaskIntoConstraints = NO;
v5.backgroundColor = [UIColor blueColor];
UIView *v6 = [UIView new];
v6.translatesAutoresizingMaskIntoConstraints = NO;
v6.backgroundColor = [UIColor yellowColor];
// add the subviews
[container1 addSubview:v1];
[container1 addSubview:v2];
[container1 addSubview:v3];
[container2 addSubview:v4];
[container2 addSubview:v5];
[container2 addSubview:v6];
// Add the containers to the root view (in this case self.view)
[self.view addSubview:container1];
[self.view addSubview:container2];
// Add constraints for the containers
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[container1]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(container1)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[container2]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(container2)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-64.0-[container1(==100)]-[container2(==container1)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(container1, container2)]];
// Add constraints in both VFL and regular NSConstraints to the subviews of container 1
[container1 addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[v1]-[v2(==v1)]-[v3(==v1)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(v1,v2,v3)]];
[container1 addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[v1]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(v1)]];
[container1 addConstraint:[NSLayoutConstraint constraintWithItem:v2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:v1 attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f]];
[container1 addConstraint:[NSLayoutConstraint constraintWithItem:v2 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:container1 attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f]];
[container1 addConstraint:[NSLayoutConstraint constraintWithItem:v3 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:v1 attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f]];
[container1 addConstraint:[NSLayoutConstraint constraintWithItem:v3 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:container1 attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f]];
// Add constraints in both VFL and regular NSConstraints to the subviews of container 2
[container2 addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[v4]-[v5(==v4)]-[v6(==v4)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(v4,v5,v6)]];
[container2 addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[v4]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(v4)]];
[container2 addConstraint:[NSLayoutConstraint constraintWithItem:v5 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:v4 attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f]];
[container2 addConstraint:[NSLayoutConstraint constraintWithItem:v5 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:container2 attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f]];
[container2 addConstraint:[NSLayoutConstraint constraintWithItem:v6 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:v4 attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f]];
[container2 addConstraint:[NSLayoutConstraint constraintWithItem:v6 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:container2 attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f]];
Attached are screenshots on iPhone 5s, iPhone 6 and iPhone 6 Plus respectively:
iPhone 5s
iPhone 6
iPhone 6 Plus
I hope this at least point you in the right direction =)
disable autolayout and use autoresizing masks in the interface builderHandling Layout Changes Automatically Using Autoresizing Rules

How to align UIImageView to the centre of the view controller?

I want an imageview to appear centre at the bottom,i added the imageview to another imageview in the view controller.the result is imageview is appearing at the bottom but not exactly at centre, can any one suggest what is wrong in my code?
-(void)viewWillAppear:(BOOL)animated
{
UIImageView *imgView=[[UIImageView alloc]init];
[imgView setTranslatesAutoresizingMaskIntoConstraints:NO];
UIImageView *mspimgvw=[[UIImageView alloc]init];
[mspimgvw setTranslatesAutoresizingMaskIntoConstraints:NO];
mspimgvw.image=[UIImage imageNamed:#"msplogo.jpg"];
[self.imgView addSubview:mspimgvw];
[self.view addSubview:imgView];
CGFloat bottom=0;
[imgView addConstraint:[NSLayoutConstraint constraintWithItem:mspimgvw attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:imgView attribute:NSLayoutAttributeBottom multiplier:1 constant:bottom-40]];
[imgView addConstraint:[NSLayoutConstraint constraintWithItem:mspimgvw attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:imgView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:bottom-40]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[imgView]|" options:0 metrics: 0 views:dicViews]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imgView]|" options:0 metrics: 0 views:dicViews]];
}
I want image to appear to the centre of the view controller.What to change in my code?
Here you go:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.f
constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.f
constant:0.f]];

UIButtons in Landscape dont show their titles

I have a strange thing and I would like to fi that.
I have a View which is in landscape mode. Due to landscape mode I have a button which need to change his frame:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 40.0, 160.0);
[view addSubview:button];
Normal:
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
Landscape:
button.frame = CGRectMake(80.0, 210.0, 40.0, 160.0);
All is fine, except the Title of the Button: "SHow View"
Instead of saying Show view it says this:
w
e
i
V
w
o
h
S
read this from button to top :P
This is my button title, because its landscape, but the titles go still for Portrait.
Any help appreciated :)
First of all, it seems you are not setting the rect of your button right. Remember that the third parameter, is the width:
CG_INLINE CGRect
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
CGRect rect;
rect.origin.x = x; rect.origin.y = y;
rect.size.width = width; rect.size.height = height;
return rect;
}
In button.frame = CGRectMake(80.0, 210.0, 40.0, 160.0); you are setting the width of your button to 40.
More importantly, you should use strings and struts, or even better, auto layout. Life is so much easier when you let computers do the math. For just one button, springs and struts is all you need, but if you want to create a more flexible interface, and you can target iOS 6, then you should use autolayout.
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
[button setTranslatesAutoresizingMaskIntoConstraints:NO];
[[self view] addSubview:button];
NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:nil
attribute:NSLayoutAttributeWidth
multiplier:1
constant:200];
[button addConstraint:widthConstraint];
NSLayoutConstraint *bottomContraint = [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:[self view]
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-20];
NSLayoutConstraint *centerContraint = [NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:[self view]
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0];
NSArray *constraints = [[NSArray alloc] initWithObjects:bottomContraint, centerContraint, nil];
[[self view] addConstraints:constraints];
And if you want to use springs and struts, you have to set the autoresizing mask:
[button setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin)];
These two things are much more easier in Interface Builder.