Adding Views with Equal Width to Superview - Autolayout iOS - ios

I have 3 uiviews which is added to parent view. i want the views (subviews) should have equal width in Portrait and Landscape. You can see three views share equal width in portrait but the centerview takes more space in Landscape. How to make equal width in Landscape.
Landscape:
Portrait:

As far as I can tell, the task is very trivial, you just have to set all horizontal edge relationships (e.g. view1.left = superview.left, view2.left = view1.right, view3.left = view2.right and view3.right = superview.right) as well as make all three views' width equal.
Also, don't forget to make vertical constraints, so vertical positions and heights could be calculated.

Related

how to make buttons in stackview change size depending on screen size (using main.storyboard or code)

I am trying to figure out how to make my three buttons in a stackview have relative sizing and keep the same multiplier spacing on different devices, e.g. the buttons will be bigger if i am on an ipad compared to an iphone. Secondly the spacing between left and right edges of buttons will be bigger on an ipad compared to that of an iphone device. So far I currently have three buttons in a stackview. I have added horizontally and vertical allignment to my stackview. I have played around with adding equal heights and width and changed the multiplier as well as adding constraints to the buttons however it did not get my desired result.
Here is a screenshot of how i'd like my items to be placed on all devices:
UIStackView has only static spacing. You have two options:
Change spacing inside code with viewWillLayoutSubviews. I prefer it over viewDidLayoutSubviews because changes will follow rotation animation. But if your calculations will depend on other subviews(not just self.view), these frames will not be updated yet. You can change constraint.constant like this too.
#IBOutlet var stackView: UIStackView!
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
stackView.spacing = view.bounds.height * 0.05
}
Using only storyboard, you can't add spacing constraint with modifier. But you can add a transparent view which will be your spacer, and apply width/height modifier to it. This can be used both for UIStackView and for plain views.
I prefer adding equal height constraint for all views with same size(like btn1.height = btn2.height, btn1.height = btn3.height), so I can set size with one constraint to all of them(btn1.height = superview.height * 0.1).
Something like this should work for your:
Result:

Hiding a view when orientation changes to landscape in autolayouts

I am creating a sample application in which i am copying Facebook screens in order to practice auto layouts.
When I run login screen in portrait mode, it looks perfect.
The problem is as soon as the orientation changes to landscape, all the views collapse because of header image, as shown here
What i want is that, in landscape mode, header image disappears so that other views get its space. I don't want to use scrollview.
I tried this:
headerImageView.isHidden = true
But the result came out to be this
The imageview got disappeared but didn't leave its space.
Can anyone suggest me a good solution?
P.s
Sorry for the images being this way because of my reputation.
When using Auto Layout you can leverage Size Classes.
See description below or example here: https://github.com/jonaszmclaren/AutolayoutExample
Set image view for compact width and height (wC hC - iPhone in landscape) and for wR hC (iPhone Plus in landscape) to not installed:
Constraint between text field and image view not enabled for wC hC and wR hC:
And finally for wC hC and wR hC you have to define text fields's top contraint - I did it to the top of the view.
This way, image view for portait will be visible and text view pinned to image view, and in landscape image view will be hidden and text field pinned to top of the view.
The best way is to use scrollView in such type of scenarios. If you don't want to have the scrollView, then you must give the bottom constraint for last button, and set the priority low of that particular constraint. It will work fine for current screen(both landscape and portrait), but when you'll go for small screen i.e 4s or 5, then purpose of auto layout will fail.
If you hide the image than it will only not show to user But Space will be used by Image on screen. Better Approach is you can set the Height Of Image 0 when orientation change to Landscape. You can create the Outlet of Height Constraint of Image and Change it according to Orientation.This method is called before orintation change. You need to Create outlat of Height constraint of Image.
#IBOutlet var heightConstraint : NSLayoutConstraint!
override func willRotate(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval)
{
if toInterfaceOrientation == .landscapeLeft || toInterfaceOrientation == .landscapeRight{
// Imageview height constraint outlate
heightConstraint.constant = 0
}
else{
heightConstraint.constant = 100
}
}
isHidden will just changed the visibility of the view. It will not remove it from that position. To solve this issue create a outlet of height constraint of header view and changed it to 0 on orientation change.
ex:
headerViewHeightConstraint.constant = 0.0
self.view.layoutIfNeeded()
and to restore it on portrait mode set height again.
headerViewHeightConstraint.constant = // height value which you want to set
self.view.layoutIfNeeded()
Another option could be to place your view inside a stack view. Then hiding the headerImageView should recover the unused space.

My scrollView does not wants to scroll

This is my setup:
I do not know what I am doing wrong. The image view is bigger than the size of the view and of the scroll view. The constrains are set al followed:
Scroll view: equal heights to View * 0,5, equal width to View, center Y and X to View.
View (inside Scroll view): pinned all zero's inside Scroll view, equal heights and width. I also tried instead of equal heights and widths to center X and Y inside Scroll view, but it won't scroll.
How can I let the Scroll view scroll? Thank you.
Add a leading, trailing and top constraint and equal height of UIScrollView to superview with 0.5 multiplier. Now to your contentView (the UIScrollView subview), add a leading, trailing , top and bottom constraint. Also add equal height and width to UIScrollView. Set the height to a priority of 250. Add constraints for UIImageView inside this contentView.
Since the contentView will have a fixed height of low priority equal to the UIScrollView height. This fixed height constraint will break once the UIImageView total height(based on the constraints you add) will get larger than the UIScrollView height and the content will become scrollable. So at the very least you will always have a view half the screen size and become scrollable once the content becomes too large vertically.
You need to give contentSize to scrollview.
ScrollView.contentSize = CGSize(width: 1000, height: 500)
Which constrains have you given to imageview?
set constraint of imageview:
Trailing ,leading,top,bottom - 0 and also give height constraint.

Interface builder constraints for enlarging buttons with the screen size

really new to the interface builder. I have 5 buttons evenly spaced. Setup in the iPhone5 screen. I want the spacing between the buttons and the boundaries to remain the same but the buttons to grow in size with the screen (keeping the same aspect ratio).
How would I setup the constraints for this ? Do I need to put invisible spacers between the buttons or something to do this?
Do like this:
Put all buttons inside UIView
Set constraint to UIView as leading, top ,Trailing, height and width.
Set constraints to all the buttons inside UIView as top,leading,width and height.
Then select first button and UIView together, and make them equal widths and set the multiplier of this constraint as per your number of buttons need, at this point set priority of UIView's width constraint to 900 (this is important). Same with button's width constraint.
Now select all buttons and set them as equal width and set the multiplier of this constraint as per your button's width.
Delete width constraint of all the buttons except first one.
View heirarchy:
Final Output:
Solutions:
I have started implementing constraints from the button in the center i.e. Button4
1) Constraints on Holder View
HolderView.centerY = superview.centery
HolderView trailing/leading constraints to superview
2) Constraints on Button4
Button4.width = Button4.height
Button4.width = HolderView.superview.width * (1/7) - 10
(yes it is not a typo Button4.width is relative to screen width not its holder view's width)
Button4.trailing to Spacer, Button4.leading to Spacer
Button4 bottom/top constraints to superview
Make all other buttons equal to Button4 (button in the center)
3) If you need to have the same arrangement for any number of button you just have to play with width constraint of the button in the center
Sample Project :
Link to Sample Project
Note: This solutions will work on only odd number of buttons

Autolayout: Hiding a UIView without knowing Height constraint

I have 2 views(say topView and bottomView) in my UIViewController with topView at top. Both views grow with aspect ratio constraint. topView and bottomView has 0 vertical space between them. I want to hide bottomView in a particular case. But problem is that I don't have height constraint available for it. I only have Vertical Space constraint between topView and bottomView. So I decided to move bottomView under topView. I tried to do following in view controller's viewDidLayoutSubViews
self.verticalSpaceConstraint.constant = -1*[bottomView intrinsicContentSize].height;
and
self.verticalSpaceConstraint.constant = -1*[bottomView bounds].size.height;
The intrinsicSize always returns (1,1) and bounds always returns (0,0,320,568). How can I achieve this it?
You can add height constraint (with constant value 0) and aspect ratio constraint both at a same time to the view, but these constrains should have different priorities and non of these with priority 1000 (required). Then to hide view just set programmatically priority of aspect ratio constraint lower then height constraint or vice versa to show it. Hope this helps

Resources