Subview goes out of screen bounds iOS (Auto layout) - ios

I am developing a component in a separate xib file which I then add to my controller. The issue is that the trailing side of my inner containers goes out of bounds of my outer container. To be more precise my subview width fits into my view controller, but elements inside subview are going out of that container. The constraints are all set to 0 (top, bottom, trailing, leading). I have set clip subviews to true for the container. Images below demonstrate the problem. Right label on the first image goes out of container constraints when i build the app. The same will be for every element. I have played with the trailing constraint and if I set it to -40 the label appears on the screen however I feel that there has to be a better solution.
The size class that i'm using is Compact:Regular.

Actualy, you came up with the right solution. For components like labels or image views (components, that can determine their sizes implicitly based on content), it is only necessary to set one constraint in each dimension. In your situation, it should be enough to set trailing and, for example, center Y of label. The rest will be dependent on label content itself
Update
Take a look Apple's guide on autolayout and Intrinsic Content Size

Related

Basic Auto Layout - nested width and dynamic height

Simple goal, but it demonstrates situations where Auto Layout gives me a headache. I want to have a stack view with a width of 256pt and a dynamic height based on layout (I shouldn't have to manually specify the height).
Inside it should be an image view sized 64pt x 64pt, which should also be centered horizontally as well as constrained 8pt from the superview's top. Note that the image view isn't the only child, hence why the stack view's height must be sized dynamically.
Auto Layout now tells me there's a conflict between the 256pt width constraint of the stack view and the 64pt width constraint of the image, as well as some mysterious "leading = Image.leading" and "trailing = Image.trailing" conflict which I can't even delete nor find.
Am I missing out something here regarding Auto Layout? I expect all logic to be contained in the interface builder, so no code should be required.
Running Xcode 9.1
Layout image
There is nothing to confuse. iOS clearly telling you the issue.
StackViews take size based on the size of child components (this is called implicit size) unless its been overriden manually as in your case which is 256pt.
Because stackView is just a container for multiple childViews stacked either horizontally or vertically, now because you have added only one imageView to it, it adds the leading and trailing constraint to it which makes absolute sense because you added a single view to the stack of view's , now what should stackView do? stretch childView (in your case imageView) to its own size.
But then you did not allow it because you added width constraint to imageView now when it tries to increase the imageView's width imageView's constraint wont allow it.
Hence it is complaining that there are too many conflicting constraints. Thats all :)
some mysterious "leading = Image.leading" and "trailing =
Image.trailing" conflict which I can't even delete nor find.
You cant delete them because, imageView is the only view inside stackView. Because there is only one child view to stack, stackView will start from left side (leading) to right side (trailing). Because now stackView has its own width it tries to change the width of imageView to reflect the same! But images width constraint prevents it from happening.
What are you trying to achieve with imageView added to stackView. If there is only one view in stackView, adding stackView does not make any sense. Reconsider what you are doing.
Finally, when you have only one childView in stack view, adding horizontal center does not make any sense (no matter vertical/horizontal stackView).

making an auto layout of UIimageView and textview inside scrollview for iOS 10.2 in xcode8

I am making a note taking app in xcode8 for iOS 10.2. The note is consist of a textfield, textview and imageview. I am adding textview and imageview in separate scrollviews (to provide the facility of zooming and adjusting image). Then I have added both scroll views in a stackview to ensure that imageview and textview stands side by side in a landscape mode. To do that, I have added variation to axis property of stackview( width=any, height= compact and Gamut=any, and set that to the horizontal, as shown in right corner of screenshot to see view hierarchy without any constraints).
I have tried many constraints but, every time it fails to adopt. Let's take an example, I am adjusting size of the scrollviews on the size of content(by setting top,bottom,leading and trailing constraint), the stack view is adjusted to the main view. Now, the only thing that needs to be adjusted is text view and imageview with respect of stack view. But, here is the tricky part If I include a fixed trailing constraint of text view to the stack view; it will work in portrait mode.As soon I turn into landscape mode that constraint will not work(the trailing constraint which have 0 distance from stackview) because the edge will be side to the imageview not to the stackview(because I am putting image and text side by side as explained above) which will make textview larger than required, same goes for imageview's leading constraint to the stack view and vertical distance constraint betweem image view and textview.I think the root of the problem is I have made a variation to the axis of a stack view (in order to get text and image side by side in landscape mode) but, that was necessary part.Can anyone have solution for this? Do you think there can be other problem? Should I choose Intrinsic Size of scrollviews to placeholder option or let it be system default?
Thank you.
So I hope I understand the question and I will try to walk you through what I understand you hope to accomplish. I preface this by saying I just started using UIStackView because of backwards compatibility.
Note. To get the magic of ScrollView with AutoLayout I almost always embed them in another UIView. There are reasons to not but in this case you will see how valuable this is to AutoLayout.
Step 1) Drag your UIStackView and add Top,Bottom,Leading, and Trailing. Now add 2 UIViews and set the UIStackView to Fill Equally. It will now look like the image(Background colors to check your work).
Step 2) Now add a UIScrollView to each of these UIViews. Add Leading,Trailing,Top,and Bottom on each of these.
Step 3) Add a UITextView and UIImageView to the ScrollViews respectively. Now Autolayout is mad at us :( but we will fix that.
Step 4) Drag from the UIImageView to the View that is holding the UIScrollView(First Set of Views we added). See image
-Choose the option to add Equal Widths. See Image
Repeat the same step but add Equal Heights. Now add Top, Bottom, Leading, and Trailing to the ScrollView.
Step 5) Repeat exact Step 4 with UITextView
Your final view hierarchy should look like this.
Now you can rotate your UIStackView and do what you want I think.
And Horizontal
Side by Side Preview
I did add a <= 0.1 equal heights multiplier on the textfield at the top but I don't know if that was necessary.
Enjoy.

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 .

ios - UIScrollview w/ autolayout on Xcode 6

I have been struggling for days with this implementation, and even though I have tried to do every tutorial I found on the web, I still cannot make things work the way I want.
Basically, I am trying to put my login form in a scrollview, so that it takes the whole screen at first (and on all iPhones / iPads), and if the keyboard appears everything should move. The problem IS, my view doesn't take the whole screen... Either it is too large, or too high, even though in Interface Builder everything seams correct (from layout to constraints). Below and image of the layout I want to achieve (I am using an universal storyboard, with Size Classes and Autolayout enabled):
http://img4.hostingpics.net/pics/829115app.png
Can someone point me out on achieving this layout ?
Thanks in advance.
I would suggest pinning top, leading and trailing spaces of your scroll view to its superview. And set a bottom space constraint less or equal to the keyboard's height if you set it to 0, the scroll view won't be able to resize.
With your form layout set vertical center constraints and top space to superview constraints for your top label being more or equal than the distance you set in the IB, and then you can set relative space constraints between each of the components.
Hope I answered your question.
Edit: Just the provided project and got it working. I think the problem is caused by it being a containerView inside a scrollView. And both the container and the scrollViews content view adapt to the size of its subviews. Because of that, setting relative constraints won't help.
What I did was to set an explicit size (screen's size) to the containerView and setting setTranslatesAutoresizingMaskIntoConstraints(true) to it.
I modified your project and uploaded it here

How to use ScrollView and ContainerView with Autolayout checked

I have trouble implementing scrollview with auto layout:/
Here is simple "Hello World" project with that problem: http://www.sendspace.com/file/cg96by
But the problem… I need to create scrollview, but also I need to use auto layout. So I created pure single view application, added (like I saw in some tutorials) Scrollview (the same size as main view), added constraints (all zeros) and then add Container View (the same size as scroll view), add constraints and.. It's didn't work:/ It doesn't scroll. Here is the screen of that situation:
Now, when I delete two constraints named: Center X and Y Alignment (marked on the screen), it works perfectly, but Xcode5 doesn't quite like it :/ and shows some errors like on the next screen below.
Why does he want width and heigh 0 ?!
Actually ContainerView doesn't matter. I've also tried with image view. When you select "Add missing constraints" it also add Center X and Y Alignment. And scroll doesn't work. When you delete them, scroll works but you have this warring:
Ok, I find manually adding the autolayout constraints to be quite confusing, using the "Add New Constraints" button at the bottom really comes in handy, try this, after you get each view where you want it use that way of adding layout constraints for each view (ie scrollView, containerView, UIImageView) I did this, and heres the example, select each constraint as I have so that the top, left, bottom, and right edges are set, this should do exactly what you want.
You will probably want to erase all your current constraints and then implement them this way.
heres the layout like you want http://cl.ly/image/463k2043401L
and heres the example adding the constraints: http://cl.ly/image/472l2V0l3N1L
To keep it dynamic so that you can rotate it, you will want to do the above for all view BUT the container view... then If you control drag from container to scrollview with no constraints, you can add all of them that it suggests except for the height and width at the bottom, that satisfies any missing constraints and should do the trick, It will center the container inside of the scrollview and keep it pinned to the top, bottom, left and right, and it should dynamically change with your scrollview content size.
http://cl.ly/image/1o3k1e452W0g
Sorry for the confusion, hope this helps!
I had a similar problem and i found relative simple solution from within Interface Builder using pure Autolayout without any code.
For proof-of-concept at first remove any constraint in View Controller to if see this works.
This is sample layout:
View (main view of my UIViewController)
Scroll View (UIScrollView)
Container View (UIView)
Content View (e.g. UIImageView)
A. Scroll View width/height should be smaller that Container View width/height
B. Container View should have some determinated width/height (may be explicit width/height )
C. Do Control-drag Container View to Scroll View and add only:
Leading Space to Container
Trailing Space to Container
D. Check out those two constraints and set "constant" value for both to 0
E. Run app and

Resources