correct autolayout constraint for UIButton - ios

I have a button on my view that must be positioned in the top left corner throughout all different screen sizes, but proportionate to the margins and scaled accordingly. I had success in doing so with several other IB objects by using the aspect ratio, and X/Y Centering, but this button seems to not be complying. What constraints should I look to add?

Related

Auto layout issue for devices in the same family and orientation

I'm working on my beginner app and checked on the preview option for my app. I've noticed that across the iPhone X, 8+, 8 and SE the spacing of my objects are off. I've learned about the custom size class for various devices for different orientations but nothing what said about the same device family in the same orientations (ex: iPhones in portrait mode). This is what I am seeing.
The iPhone X looks fine but the others, not so much. I'm guessing that instead of using hard numbers for auto layout I should be using a ratio based on the height and width relative to the screen. Is that right?
Try to take Base ViewController as iPhone4S. Drag UIView called as HolderView, which should hold that UILabel and Two UIViews.
As per Design, give HolderView's width and height be same. Like Square shape.
Give Constraints as, left and right as 20px, CenterHorizontally and CenterVertically, and finally give AspectRatio to itself.
HolderView
Add UIView for UILabel to HolderView called as LabelHolderView.
Give constraints for LabelHolderView as left and right 20px, CenterVertically and Height as 90px (approx - Two lines for UILabel)
Click CenterVertically constraints and decrease Multiplier value to 0.4.
You can get answer from here that how to change multiplier value.
LabelHolderView
Add UIView for Two Action to HolderView called as ActionHolderView.
Give constraints for ActionHolderView as left and right 20px, CenterVertically and Height as 160px (approx)
Click CenterVertically constraints and increase Multiplier value to 1.3.
Inside that ActionHolderView, drag Two UIView called as PhotoView and NoteView and Embed in UIStackView as Horizontal axis, Fill Equally and 8 as Spacing.
Give constraints for UIStackView as top, left, right and bottom as 0.
ActionHolderView
Change all UIView's BGColor as per your design. Then, add UILabel and UIButton and UIImageView to respective UIViews.
For UILabel, top, right, left and bottom as 0. (number Of lines as 2)
For Two UIButtons ,right, left and bottom as 8 and height as 30
For UImageView, Width and Height be 50px (Change width and height from Size Inspector - Square shape). Give Constraints as CenterHorizontally, CenterVertically and AspectRatio to its SuperView and AspectRatio to itself
ViewController
You need to set height/width constraints for your items. I would also put your add photo/add note buttons in a view to make it easier for constraints. Don't be afraid to mess around with it, you can always to command z to restore the previous version.

Keeping aspect ratio and autolayout for different devices

I have labels and toolbars on the top and bottom of the screen with height constraints. And I got UIImage between toolbars. So toolbars and labels are keeping same height for different devices while space between toolbars is changeable.
My goal is to keep aspect ratio 1:1 for devices from SE to IPad and to center UIImage between toolbars by stretching it until it reach superview margins on sides or toolbars on top and bottom. I was tried different approaches but the best thing I could get is on below screenshot.
It's keeping aspect ratio but I can't figure out how to keep it centered between toolbars.
Constraints for UIImage:
Since I'm working on iOS 8 supported app I didn't use UIStackView and try to find a solution with constraints only.
You need to do following things :
Add a new view (says, centerView) in between the yellow and green view and give it clear color and give below constraints
Leading, trailing to superview as constant = 0.
Top to yellow view as constant = 0
Bottom to yellow view as constant = 0
Now in centerView add ImageView which have Apple logo and give below constraints.
Give it fixed height as you want.
give it vertically and horizontally centered w.r.t. its superView.

Adjusting button width and height according to device

I am attempting to create a keypad for an app that I'm playing with. The keypad will be a standard four rows with the numbers 0 - 1, a decimal, and +/-. Nothing special. I am attempting to get it to only take up 1/2 of vertical screen space. Using constraints, I pinned the bottom left button to the left and bottom of the screen, and the bottom right button to the bottom and right of the screen. I set the width and height of the left button, and then used Aspect Ratio on that button. On the remaining bottom buttons, I control-drag left to the one next to it, and select Horizontal Spacing, Center Y, Equal Width, and Equal Height I then control drag from each of the buttons above, to the button below, and select Vertical Spacing, Center X, Equal Width, and Equal Height from the list of constraints. My thinking was that the bottom left button would adjust based on the device selected, and then all of the other buttons would adjust based on this button.
Apparently, I was wrong. The buttons are nicely set up in that they remain above and next to one another, without any spaces, but they are not taking up exactly one half of the screen. Depending on the device selected, there is proportionatally more or less space above them. Apparently, I am either missing something, or I am totally approaching this the wrong way.
Any advice on how to accomplish this task would be appreciated. I'm still learning about how constraints play with one another, but I thought that my idea was sound. Make one button adjust itself to the correct size (Aspect Ratio on the bottom left button), and then force all of the other buttons to maintain the same width, height, and distance.
The bottom left button is not going to adjust its size, because you gave it a fixed width and height. The buttons should not have any explicit widths or heights set on them. They should all be set to the same size, and as long as you have constraints going from the left edge to the right, that should set theirs widths. Their heights will also be set by virtue of the aspect ratio constraints.
This will cause the buttons to just their size based on the screen size, but it doesn't make them be half the height of the screen (that could only work for one screen size with a particular aspect ratio). To make the buttons take up half the vertical height of the screen, you would probably want to enclose them in a view that was that height. However, then you'll have a conflict between the aspect ratio of the buttons, and the aspect ratio of the screen. You either need to give up on the aspect ratio, or, not pin the right side of the buttons to the right side of the screen, and use an aspect ratio that will make the buttons all fit on the screen.

How to correctly use constraints when both UITableView and UIImageView are presented on the same view controller

Suppose that I have the following view controller and this is how I want to see it on all iPhone:
If I run it on iPhone 6 it has the following look:
Here you can notice that UITableView not fit the whole screen and UIImageView doesn't placed at the bottom of the screen.
How can I achieve the required behavior via constraints in XCode 6? I thought that I need the following constraints:
Leading space and top space to container margin for UITableView
Bottom space and trailing space to container margin for UIImageView
Vertical Spacing between UITableView and UIImageView
But it doesn't work as expected even after auto-resolve constraints issues:
Thanks in advance.
Ok, a few things here:
Each view needs enough constraints to define it's x and y position, and it's width and height unambiguously. To start with, go back to Interface builder and delete all of your constraints and lay out the view as you would like it to look. You want to have control over every constraint added, don't let IB automatically resolve the issues, as in all likely hood it won't do what you want.
Do you have an image that is the size you want it to be on screen, once you've factored in #2x, #3x etc? If so, then your job will be easier, as the width and height of the image view can be defined by the width and height of the image (ie the image view's intrinsic content size).
In order to use Autolayout effectively, you need to think about your view holistically, and think about how you want your views to behave when the screen size changes, be clear in your head about the behaviour.
To achieve the layout you want, I would do the following:
Constrain the tableview's leading, top and trailing edges to the superview, with a constant value of 0. This means it can get wider and thinner with the device, it will stretch horizontally, but always stick to the top. This has defined the tableview's x and y position, as well as it's width (height still to go, but keep reading...)
Constrain the image view to match the horizontal centre of it's superview (x position defined) and constrain it's bottom edge to the superviews bottom edge (y position defined). If've you've got the right sized asset, then that will take care of the width and height too. If not, you could go ahead give it explicit width and height constraints.
Now we can constrain the tableview's bottom edge to the top of the image view, with a constant of 0 (ie touching). Note we haven't give the table view an explicit height constraint, so as the device screen grows vertically, the table view will stretch vertically.
Autolayout is hard at first. I'd recommended lots of reading to get over the initial hump, really get to know what a constraint is doing, it's limitations, and the way in which the system parses constraints to translate them into frames. This book is really good, and really helped me learn:
http://www.amazon.co.uk/Auto-Layout-Demystified-Mobile-Programming/dp/0321967194
Best of luck
First make sure you have selected the correct size class. The 'Compact Width | Regular Height' size class must be selected in the Interface Builder. Now add the Trailing space,Leading Space, Top space and Bottom space constraints to the table view. For the image view set the view mode to Aspect fit and add the constraints : Align Center Y ,Top space,Bottom space, Leading space, Trailing space and Aspect Ratio .

Making a view centered on the remaining space

I have this viewController that shows a navigationBar at the top (white box on top) and a toolbar at the bottom (orange box in picture).
Because the navigationBar is something iOS is adding to the viewController, when the viewController is visible, self.view's high will be reported as the screen size minus 44 points.
I have added an imageView to the view and I want it centralized between the navigationBar and the toolbar, like seen in the following picture.
What I did was to add a constraint to centralize vertically the imageView. As you see in the picture Xcode shows that the imageView is perfectly vertically centered as I want but this is not what happens when the app runs (thanks Apple).
In practice this is what happens: suppose I am running it on iPhone 5. iPhone's 5 screen high is 568 points. Because there is a navigation bar, the hight of self.view will be 524 pt (568 - 44). The constraint stupidly will disregard the top 44 pixels where the navigation bar is and centralize the imageView on the are between the bottom of the navigationBar and the top of the toolbar. The result is that the imageView will be closer to the bottom.
This imageView is carefully chosen to fill completely the space between the toolbar and the navigationBar when the app is running on iPhone 4. Also this imageView has to respect an aspect ratio constraint. Exactly like this:
Instead of centralizing the imageView using a vertically centered constraint I tried to add a top constraint to the superview and a bottom constraint to the toolbar. That works fine in all iPhones, except on the iPhone 4, where these two constraints force the imageView into another aspect ratio, like this:
So, what kind of constraint I have to apply to the imageView to make it center on the space between the navigationBar and the toolbar without losing the aspect ratio?
If you want the view to be centered between the navigation bar and the tool bar, then deselect both "Under Top Bars" and "Under Bottom Bars" for your controller. Add a centerY constraint to your image view, give it 0 length spacing constraints to the 2 sides, and finally, the aspect ratio constraint. I tested this, and it worked at all sizes, with a 1:1 aspect ratio. If you want a taller aspect ratio (your image looks like ~1:1.2 w:h) then you need to do some additional work to make it turn out right for the 3.5" screen because there's not enough height to get that ratio with the image view being full width (assuming that you also have the status bar showing -- if not, then these constraints should work for the 3.5" screen). I can edit my answer to include how to do that, if you say what aspect ratio you want, and if you want some minimum spacing between the two bars, or whether you want the image view to be as wide as possible while still maintaining its aspect ratio (which would mean there would be no space to the two bars).

Resources