Using Xcode 7.2, Autolayout, I have a UITableViewController embedded in a Container View.
The Container View was added view the Story Board and dragged to the edges of its super view. The UITableViewController was added to the Story Board from the Object Library. I am not using any Constraints to "lock" the width and height to the Container View's Super View but I don't think I should have to.
I am not using any constraints at all, in fact, I have just dragged the 4 edges of the Container View to the Super View 4 edges and the UITableViewController was dragged into the Story Board from the object library and embedded in the Container View.
The Super View of the Container View Autolayout is Any Any and the UITableViewController Autolayout is Any Any.
I have no issues with iPhone 5 but iPhone6 plus you can see in the screenshot of the iPhone simulator below.
This is not an issue of not having enough rows, there are more rows in the UITableViewController if you scroll in the iPhone simulator.
My Container View is dragged to the 4 edges of the Super View and says the following if I even wanted to add constraints:
The answer is in the question:
I am not using any constraints at all
Use constraints.
Add 4 Autoloayout constraints, edge to edge, vertically & horizontally:
top to bottom of top layout guide
leading to container leading
trailing to contrainer trailing
bottom to top of bottom layout guide
All Interface Builder does when you use a container view is place a UIView into your storyboard, then add some connection options that aren't usually there. As a result, the usual Auto Layout rules still apply: your container view was not resizing, so its child UITableViewController was also not resizing.
Anyone else who encounters this problem can resolve it just by adding constraints for the leading, trailing, top and bottom edges of their container view.
Related
I tried to create a custom freefrom view with interface builder.
I have a UIView which is containing a UIImageView and UILabel.
I set the constraints to adjusting the Label according to the Image etc and a margin to the superview.
Now I want the superview to exactly fit the subviews. But when I press Editor -> Size To Fit Content, the superview is not resized completely and the constrains are in conflict. What there appears is a implicit constraint ("iPhone Portrait Screen Height"), which can not be altered/deleted. See Screenshot below:
While not ideal, depending on how your XIB is structured and how you are referencing the view, you could create a "scratch pad" view and place your custom view inside of that just to see how everything will layout. That is if you're setting the view to an outlet defined in the XIB's File Owner, you can just connect it to the view you've created inside the "scratch pad".
For example, I created a container view with a square and a switch inside. The top example complains of conflicting constraints and doesn't layout correctly, while the bottom example shows the same thing centered in a throw-away view. Again, not ideal, but it's working for me.
Edit: I just realized that some size class constraints may be lost once the "scratch pad" view is discarded so that is another wrinkle to consider. Still looking into this.
Just to make it simple forget the label for the time being. You have already added the width and height constraint of the image view, now instead of using sizetofit content, try adding leading, trailing, top and bottom constraints between the image view and it's parent view. With that your parent view should fit the image view.
The same technique (constraints to parent view) can be used to get it work with the image view and label together.
I noticed that when I physically dragged the superview's width and height to satisfy the constraints, the red constraint errors went away along with the "iPhone Portrait Screen Width" constraint. In other words, my constraints dictated that my subview be bottom aligned with its super view. If I dragged the superview's bottom edge up to align flush with the subview, the errors went away. Still seems buggy and unintuitive.
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
I have constraints set in interfacebuilder that have some UIViews near the bottom of the screen. They have constraints set to have their bottom, leading and trailing edge attached to superview.
However when I view the xib within a 3.5 simulator the views are off screen(below) instead of maintaining that explicity set distance from the bottom of the 'superview'
This view is made in a xib, and then I load the xib into a view controller in code.
So my question is how do I get the bottom and top layouts to apply to these buttons inside this seperate xib I have? The buttons seem to be hard coded to layout depending on the design size of iphone 5.
Thanks
Your problem isn't the buttons, but the parent view which contains them. Make sure its constraints are set to adjust to the bottom of the screen.
In xcode 5 using storyboards how would one make a fully operational vertical scrolling scrollview, with AutoLayout ON?
Considering the subviews have hierarchy:
1.UIView
2.UIScrollView
3.UIView (lets call this UIDetailView to make things easier)
Please be specific from code to constraints to wether any of the views HAS to be smaller etc.
UIScrollView with Autolayout within Storyboards Just Works
I've seen a number of people recommending the 'Container View' approach, AKA brute force, to solving the problem that they don't understand. It is non-optimal since you now have lost a big advantage of the scrollview by making it think the content is the entire scrollview rather than the subviews immediately attached to the scrollview.
Here is how I did it in the example that follows
--UIScrollView
|-> UITextView
|-> UILabel
|-> UIOtherStuff
When placing a UIScrollView into a UIView in a Storyboard just pin the edges to the 4 sides of the UIScrollView to the UIView. Now add your content to the UIScrollView making sure that you provide a minimum of two constraints for each dimension. The great thing about Autolayout is that it figures out how big the contentSize of the scrollview, or UILabels for that matter, needs to be based upon the size of the content inside it. AKA intrinsicContentSize. So if you are given a warning 'Ambiguous content size for scrollView' you know that you have not given the content enough constraints. For example, you might have given Top, Bottom, Left, Right spacing distance between views but the subview you're constraining needs a height too since an infinite vertical plane like this UIScrollView could assume your view was from zero to infinitely high.
To put it another way the Apple guide on Autolayout by Example makes a simple 3 point plan for success:
Create the scroll view.
Place the UI element inside it.
Create constraints that fully define the width and height of the scroll view content.
That top TextView with 'Min melding til' is also growing as you type more lines into it and the whole ScrollView grows to contain it. While I override the UITextView class to return a modified height constraint, the ScrollView itself works correctly without coding.
One last thing, lots of posts related to Autolayout try the magical fix-all incantation translatesAutoresizingMaskIntoConstraints = NO. This is only necessary if the view is created programmatically.
This blog post details how to use a UIScrollView with Autolayout ON, using a pure autolayout approach. Note though that all constraints in the blog post are defined through the Storyboard.
The approach in the post assumes the following hierarchy:
1. View (main view of my UIViewController)
2. Scroll View (UIScrollView)
3. Container View (UIView)
4. Content View (e.g. UIImageView)
I guess the Container View will be your UIDetailView, and the Content View will be any UIView inside your UIDetailView.
https://happyteamlabs.com/blog/ios-how-to-use-uiscrollview-with-auto-layout-pure-auto-layout/
The documentation clearly states how to do this:
A UIScrollView in auto-layout will always resize itself to fit the content (UIDetailView).
So you have to set up your views like this:
UIView: Position with constraints.
UIScrollView: Bind to UIView with constraints.
UIDetailView: Set size (intrinsic content size), max out compression-resistance, set top-, bottom-, leading- and trailing constraints to UIScrollView to 0 manually.
I had a similar problem and i found relative simple solution similar to DJ S's 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
Because of the new iPhone 6 and 6+ screen sizes, I had to make a few tweaks to DJ S's solution.
The goal
Position a UITextView inside a UIScrollView, and also have 15 pt spaces from the left/right screen edges.
Views
1. Main View (main view of my UIViewController)
2. Scroll View (UIScrollView)
3. Container View (UIView)
4. Text View (UITextView)
Solution
For the spaces, I added 15 pt horizontal trailing/leading spaces from UIScrollView->Main View. To make the UITextView's width relative to the screen width, I added an Equal Widths constraint from UITextView -> Main View and set the value to -30 (2 * the 15 pt horizontal space). Now, the UITextView's width will dynamically adjust for any screen size.
The UIScrollView should have Scrolling Enabled. The UITextView should not.
I am attempting to layout a screen design using constraints (auto-layout) from interface builder and hope to avoid coding constraints, but I would accept an answer for either case I guess.
I have two subviews in a contained in a top level view. I want to fix vertical distance of the first subview to the top of the screen (I was able to accomplish that - common use case for a vertical space constraint). I want the second subview to float (vertically) in the center of the distance between the bottom of first subview and the bottom of the screen. The idea is that the design responds somewhat to iPhone 3.5" vs 4" dimensions.
I am having trouble defining a constraint or set of constraints that would accomplish this.
I have tried setting inequalities on the vertical spacing constraints between the second subview and the top of it's neighbor (the first subview) and the bottom of the superview, and playing with the priorities of those constraints.
An idea that was suggested in a few other related posts on SO is to use a container that is pinned to the bottom of the screen, as well as the pinned to the bottom edge of the first subview, and then center my second subview in the container. I was hoping to avoid complicating the view hierarchy if possible, but maybe that isn't easily avoided.
Any thoughts or suggestions?
UPDATE
This answer describes how to do this in Xcode 6.0 (and probably works in Xcode 5.0 and 5.1).
ORIGINAL
If you want to do this with auto layout, you have to add at least one spacer view. It doesn't have to be the superview of the vertically-centered view (or any other view), so it has a pretty minor effect on your view hierarchy.
I recommend not trying to set up constraints in Interface Builder in Xcode 4.6.3. It's just too painful. But if you really must, this is doable.
Create a spacer (a plain old UIView) from the bottom edge of the top-hugging view to the bottom edge of superview. Set it to hidden. Give it constraints to the top-hugging view and the left and bottom edges of the root view, and pin its width. My spacer width is 10:
Add your middle view (here, a button). Give it a “Horizontal Center in Container” constraint. Then select both the middle view and the spacer view and give them a “Vertical Centers” constraint:
Note that if you drop the middle view when IB is showing the correct guidelines, it will set these constraints for you.
You can test by enabling resizing for descendents (but not siblings & ancestors) and resizing the root view in IB. The middle view will remain centered between the top-hugging view and the bottom of the superview: