Xcode 5 Auto Layout - Embedded Tables - ios

I have a UIScrollView with several UITableViews embedded in it. I want to allow each table to expand its height as much as is needed to display all of its cells. The scroll view's frame takes up the whole screen, so its contentSize.height need to expand to fit the biggest table (which I think is the default behavior, but I mention it just in case I'm incorrect). Can this all be done on my storyboard? Or if I will need to add code to do it, I found this tutorial, but it's for iOS 6 - has any of the code for this constraint stuff changed for iOS 7?

If you know in advance how much room each table takes up you can do it purely in your storyboard, but because each UITableView is also a scrollview the default behavior of a UITableView is to fill the assigned size with content and scroll if there is overflow.
If you do not know the height of the tables at design time, you will need to set them at run time. See Autolayout a UIScrollView to fit content including subviews and grouped tables for an example, the short answer is to add a height constraint to your table, drag it into your controller as an outlet, and then set the height when you know it.

It can be done both ways.Manually moving UI elements through code(mentioning locations) and overriding it in did rotate or through mentioning constraints in auto layout.
This link http://www.doubleencore.com/2013/09/auto-layout-updates-in-ios-7/ provides details of ios7 auto layout .

Related

Scrollview with View loaded from xib

I have a problem here. For last 3-4 days I'm trying to the find the solution but no avail. I'm using a xib to load a view as a subview to scrollView.
I'm using iOS8 and size classes and auto-layout as well.
The problem is that the view gets added to the scrollview but scrollview is unable to go beyond a point. That is I'm not able to scroll till the bottom.
This is frustrating as I have just started to develop iOS apps.
I'm attaching the screenshots for the constraints that I have applied. Hope to get some help here.
The first screenshot is the actual view controller's view that holds the scrollview.And the Place Detail Info View is the placeholder where the view loaded from xib is added. The screenshot also lists the different constraints as well.
The second and third screenshots is of the xib file which i'm trying to load into scrollView.
Please let me know where I have gone wrong.
As said above, the issue is related with the content size of your scroll view. Just try adding width and height (either explicit or implicit: see explanation below) constraints to every direct subview of your scroll view and then define all distance constraints among those.
* By "implicit" width/height constraints I mean things like "aspect ratio", "equal width/height" relation between two views.
P.S. When dealing with scroll view-like controls and auto layout, there should be an exhaustive (some of which may seem redundant) set of constraints for subviews.
Hope this helps.
Your problem is with the view who is immediate subview of your scrollview.In autolayout,scrollView calculate its content size according to its subview.
follow these steps after removing all constarints from this view,i hope u will get your problem solved.
1.for your scroll view,set all 4 constraints i.e leading edge,trailing edge,superview and bottom constraints.
2.now for the view that is immediate subview to your scrollview,set all 4 constraints (leading,trailing,top and bottom),along with these set height constraints and make width equals to scrollview.
if your immediate subview's height is greater than your screen size or scrollview,it will scroll for sure.
run and check whether you are able to scroll and proceed furthur.
after step 2,all your constarints related ambgious type error will resoved.now you can set all other constraints as usual.
for more clear understanding setting constarints in scrollview see this https://www.youtube.com/watch?v=4oCWxHLBQ-A
In interface builder itself there is an option to preview your constraints for all the available devices. This will ensure you that the constraints work fine for all the available devices from Apple. Here is a quick tutorial that will help you with it.
http://adoptioncurve.net/archives/2014/08/working-with-size-classes-in-interface-builder/
Once that is verified and you are still not able to find a suitable solution, then probably there is something wrong in the content size for your scroll view. Try to increasing your scroll view content size.
I hope this should solve your problem.
Happy coding. Cheers :)

iOS: animate UICollectionView vertical expansion with constraints?

I've a view controller with a UICollectionView on top (using the default grid layout) followed by other controls below it. As I add / remove cells to / from the collection view, I want it to expand / contract in the vertical direction (so it has enough rows to show all of the cells and no more), and all controls below it to move down / up the screen accordingly. If you imagine how email app UIs work when you add / remove addresses, that's the effect i'm trying to implement. Achieving this effect using constraints, though, is eluding me. Any help would greatly, greatly appreciated!
What I did:
removed all constraints in IB
added a height constraint on the collection view and connected it to an IBOutlet
had IB add missing constraints
add an observer for the collection view's contentSize property
Now, when I add a cell to the collection view and tell it to reload, i'm notified when the contentSize changes and can set the constant for the height constraint to the contentSize height. Result: a collection view that resizes to fill it's content, with the other controls moving up / down as needed :-)

Autolayout scrollview with collectionview

I have been struggling with this for a few days now, and I am looking to see if someone can help me with this AutoLayout problem.
In my iOS7 application, I have a UIView that has a UIScrollView and inside it a UIView(container) with some elements positioned. I have in there, a UIImageView, UITableView, UICollectionView, UITextView and a MapView. There is no height constraint on the UIScrollView and the container UIView. There are no height constraints on the UICollectionView and the UITextView.
What I want to accomplish is
The UITextview should expand to the content size as in all the text should appear without any vertical scrolling enabled for the UITextView.
The UICollectionView should always show all items and there should not be any scrolling enabled there as well.
Overall, I want a UIScrollView with items in it, that scale based on content. I have tried numerous things, but failed.
If anyone has pointers or suggestions on how to go about doing this, it would be very helpful.
OK, I would go about this in a completely different way.
First, get rid of the scrollView completely.
Just use a UICollectionView for this entire interface.
The UICollectionView can take a UIView for a section header. Make this UIView with your UITextView inside. You will need to manually calculate the correct height for your UITextView (and UIView).
Something like...
CGSize size = [theText sizeWithFont:<the font used> constrainedToSize:CGSizeMake(desiredWidth, CGFLOAT_MAX)];
Then just populate your collection view.
By doing this your collection view will control all the scrolling. Because you have set the textview to the correct size in the header you will have all the text there.
This is how I would go about it:
I assume your issue is with the height of the views, that affect the scrolling.
In the textViewDidChange: I would set the frame of the UITextView same as it's contentSize. When they are both the same, scrolling gets disabled.
After populating your UITableView and calling reloadData, I would set it's frame same as it's contentSize.
The mapView (MKMapView, I suppose) has the same frame throughout, I suppose. So you just use it's fixed height. If it changes height, you must store it's changing height each time it changes.
Once you have all the heights, add them up, and set the frame of the outer view same as then combined height of the inner view. Iterate this to all nested views, beginning from innermost views, and moving to outer views.
The catch here is, every time your content changes, the frames have to be resized. Hence changing the frames in textViewDidChange:, after reloadData, etc makes sense.
EDIT : One thing you might want to do first is, getting rid of redundant views. Your view hierarchy seems Rube Goldberg to me. The lesser views you have, the lesser work you will have to do.
Ok.. so I solved this problem by creating a IBOutlet for my NSLayoutConstraint on the UITextView in question.
I simply computed the height and then applied it on the constraint and it worked..
#Fogmeister - Your solution will also work, but it would require me to rewire a whole UI page.. Your approach is definitely a feasible one and shall keep in mind for future iOS apps..

What is the easiest way to create a scrollable form for iOS

I have been struggling with IB and auto layout and figure there must be an easier way to create a simple scrollable form with multiple fields on it. The width can adjust to the device screen width (or in the case of the iPad to the details view of a split view.
The basic layout is simple a label and underneath a field (in some cases the field must have a minimum height) repeated for each attribute.
I think I must be doing something completely stupid or IB's autolayout is hopeless, I suspect the former. In any event whatever I do in IB fields just adopt whatever constraints they feel like it seems. Even when I set a constrain it seem IB just replaces it sometimes.
Currently I am using a view with a fixed height and width that fits the screen and laying out fields on this form, however its a complete nightmare having to pin every field in almost every direction. And then IB complains about a million constraints that it can't satisfy.
Hopefully someone has a better way of doing this they are willing to share - perhaps it might be best just to write some code to set up the constraints rather than relying on IB ?
Thanks
You are right UIScrollView and autolayout is not clear at first look.
You have to understand that when you are adding layout constraints for a view inside scroll view, the superview is content view of scroll (not the view of the UIScrollView) that can be more or less then current view of the ScrollView in IB.

Resizing a UITextView in UIScrollView using Auto Layout issue

I really hate to ask here because I usually try to figure things out on my own. But on this one I've stuck for days and can't find a solution anywhere online.
I have a ScrollView containing multiple subviews. I've got an image view and two labels at the top with fixed heights. Then there is a UITextView and another ImageView (see pictures).
I add the text to the text view programmatically so it should have a dynamic height and the ImageView should move to the bottom so you can scroll. I don't want the TextView to be scrollable in itself but I want all the subviews to move as well.
I know I should be able to solve this issue using constraints. But I feel like I've tried everything and nothing worked yet. It worked when I disabled auto layout and moved the views manually. I'm wondering if there is a better way though.
As you can see I pinned the TextView to the ImageView above with a 1,000 priority and to the ImageView below with a 1,000 priority. The height constraint can not be deleted so I set it to the lowest possible priority. The ImageView on the bottom is pinned to the bottom of the superview with an absolute height. Its height constraint also has low priority. (I can post an image of the ImageView's constraints, if it helps)
I also tried adapting the frame programmatically but this is not working well in combination with auto layout. (If it helps I can of course post the code)
What am I doing wrong? Shall I just disable auto layout and do it manually? This seems unclean to me. Is it even possible to do?
I really appreciate your help :)
Greets,
Jan
Make sure the Scrolling Enabled attribute on the UITextView is unchecked in Interface Builder. I believe that the Auto Layout system takes that into account when it calculates the intrinsic content size.
If somebody is struggling with a similar problem: This is what I ended up doing:
Remove all subviews from the ScrollView in IB
Programmatically add a single UIView to the ScrollView.
Add all the views to the UIView as subviews (move them using setFrame)
Set the Frame of the UIView appropriately to the subviews
Set the ScrollView's contentSize to the size of the UIView.
A little more work but it finally works. This follows Apple's mixed approach guidelines that can be seen here (look for UIScrollView): http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/index.html
The problem is the height setting. You somehow have to try to delete it. If you have added other constraints that are "sufficient", it should become deletable.
At the moment you have one user constraint for the height that is "Greater or equal" and an "Equals" constraint as well. Clearly, those are not working well together.
Maybe there is a conceptual error as well. The lower image view should not be fixed in position, so the distance to the lower image view will not be a "sufficient" constraint to let you delete the fixed height.
I think it should work if
the lower image view has a fixed height and
a fixed distance to the text view above, and
the text view has a minimum height as well as
a fixed distance to the image view above
(which should be fixed in relation to the superview).

Resources