Nested UIScrollViews and AutoLayout - ios

I have seen several similar issues here in StackOverflow regarding UIScrollView and AutoLayout but now is my turn because I can't make it work properly.
My idea is to have an inner UIScrollView that scrolls horizontally (contains a set of images) and an outer UIScrollView that apart from the inner above, contains multiple UILabel, UITextView objects and scrolls vertically.
Without AutoLayout both are acting like expected but unfortunately size and origin are not right. With AutoLayout, outer UIScrollView, scrolls a bit but inner not moving at all. I can confirm that inner UIScrollView has the correct ContentSize during viewDidLoad but later in code has 0,0.
Below is a screenshot with views and associated Constrains.
Any idea?
UPDATE
For others who may face the same problem as mine.
In my case seems that the UIPageControl was messing up the whole thing. As you can see in the screenshot, I had the pager as a subview of the inner UISrollView WRONG!!!
I've simply move out the UIPageControl (became subview of the outer) and left Xcode to do the rest (Editor > Resolve Auto Layout Issues > Add Missing Constrains In View Controller). After that, UIScrollViews took tare of their selves (as Apple states in documentation). I've spent so many hours on this. I hope my solution saves others' time.
I am working on Xcode5

I've solved UIScrollView content issues with 2 steps:
Select UIScrollView, go to Editor>Resolve Auto Layout Issues>Add missing constraints
Add a IBOutlet NSLayoutConstraint for the height of whatever you are going to put inside the UIScrollView e.g. UIWebView. Hook up this outlet to the Height constraint you add via storyboard.
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightConstraint;
//set the constant to the element once it has been drawn
self.heightConstraint.constant = frame.size.height;
Hope this helps.

Related

UIScrollView bounces back when let go

I have a followed this answer Putting a UIScrollview in a viewcontroller (storyboard) to embed a scrollview in a viewcontroller (Mine is vertically instead of horizontally).
All the constrains are working except the fact that the view bounces back when it is let go. I have tried a lot of different solution, but none is working! Please help, I'm using autolayouts my main goal is to be able to show all the buttons on the screen through scrolling.
EDIT:
I have been trying all types of ways to increase the contentSize, but nothing happens - the scrollview won't scroll properly. I tried different codes from people with the same problem, but the bouncing won't stop. Am I doing anything wrong on my constraints? This is extremely frustrating, please help. My constraints (using autolayout) (as I said, I followed this answer Putting a UIScrollview in a viewcontroller (storyboard))
You have to increase your scrollView's contentSize to fit all of it's sub views.
You should add subview to scrollview, then add all other views to that subview.
scrollView
contentView
subview_1
subview_2
Then add constraints between scrollView and contentView (leading, trailing, top, bottom) and contentView should have width and height constraints set properly (set width equal to scrollView width)... the content size will be calculated automatically.... just set height

What are the correct constraints on UIScrollView from Interface Builder? Pure Autolayout from IB

I have been trying to get ScrollView to work for 2 days now, and it doesn't work at all. Most of the suggestions here on SO and other websites say that you need to pin the ScrollView to the root view and then place a ContentView (UIView) inside ScrollView and then pin it to all sides of the ScrollView (so that the scroll size can determine the contentSize... However this does nothing). There's also conflicting information out there, one video says that there needs to be a constraint from the bottom of the ScrollView to the ContentView. Neither solution has worked for me. Here is what I've been doing in most of the combinations I've tried:
UIView -> UIScrollView
Pin all sides of the UIScrollView to the UIView
Create a UIView (name it content view) and place it inside UIScrollView
Pin all sides of the UIView to the UIScrollView
Problem at this point: UIScrollView needs constraints for X or width AND Y or width. The only thing that seems to solve the complaint is setting the UIView inside the scroll view centered horizontally and vertically, but this does nothing to make scrolling work. Another option is setting the UIView equal height and width to scroll view, but again, that does nothing other than remove the complaint.
I don't understand. Isn't pinning the sides, setting the constraints? IB seems to think that this is not the case.
What are the correct constraints needed? All I need is a simple view with stacked controls (to fill out a form) and the screen needs to be able to scroll if the form is longer than the screen.
I'm using iOS for the first time, and building purely from IB for now... minimal code solution would be best.
You are half way there. First you need to decide what you are going to display in the scrollview, you have placed a content view, that needs to have an intrinsic size. You can choose to put there static or dynamic views. Static views will have their size defined at design time, and that will resolve the UIScrollView AutoLayout constraints. If instead you are doing it at runtime with dynamic views you will need to choose a default size for your content view, create an IBOutlet for the width and/or height of your views and then resize them at runtime altering the outlet in viewDidLayoutSubviews. The video you linked explains that quite clearly.

UIScrollView Getting stuck

I am working on application in which I have UIScrollView which contains 3 subViews(UIView) and each subView has different controls & has different height. This all works fine but when I added constraint to UIScrollView and subView then UIScrollView isn't working.
I also added constraint to all the controls in subviews.
So please suggest me how to solve this problem?
It happened because UIScrollView content height and width dynamic at run time.
So whenever you apply constraint on UIScrollView then add
1.X position
2.y Position
3.width
4.height
Take a View as SubView on UIScrollView now apply Constraint
1.Leading on UIScrollView
2.Trailing on ScrollView
3.Top
4.Bottom
5.Height
6.Width
Then it work fine
For constraints to work properly,
You need to add a child view to UIScrollView and add your 3 views to that child view.
The main UIView and child view should have equal width constraint set.
For reference see this

Why is my UIView within UIScrollView not scrolling?

I'm trying to setup a scroll for a UIView within a UIScrollView.
My view hierarchy is:
UIView (Controller) > UIScrollView > UIView (I'll call this subView from this point on)
I have used the IB to set the layout. I set the top of the subView to be inline with the top of the UIScrollView frame. The subView is as wide as the UIScrollView frame and extends beyond the height of the UIScrollView frame.
In the subView I have UILabels (also set up using the IB). To test the scrolling, I have one label that is just peeking above the bottom border of the UIScrollView frame. When I run the app this label would ideally be able to scroll into view, however, there is no scrolling and the label is just appearing as being cut off where the UIScrollView frame ends.
In the ViewController.m I have the following:
- (void)viewDidLoad
{
self.scrollView.contentSize = self.scrollSubView.frame.size;
}
where scrollSubView is the UIView within the UIScrollView.
What am I missing (doing incorrectly) that is preventing the scroll from working?
Thanks for any assistance offered.
Possible Issue
Autolayout is on, and it won't let scrollview work as required.
Possible Solution
Check for autolayout of storyboard and untick it.
If you dont want to set it to off, you can follow this short video
which is wonderfull to deal scrolling with autolayout. :)
UIScrollView with autolayout on

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..

Resources