Resize UIView inside UIScrollView with AutoLayout for scrolling? - ios

I have a layout as follows(Using AutoLayout,iPad):
The UIScrollView has Top,Bottom,Leading,Trailing space to the superview as 0. The UIView also has all four similar constraints. The second UILabel has its height set to 0 programmatically (since more than a screenful of text is shown here). Also, these four pin constraints have also been set up from the UIView to UIScrollView.
When the XIB is loaded, this UILabel shows long lines of text correctly. But scrolling does not work. This is a screenshot of the running app on an iPad:
The yellow background is set for the outermost view and the grey one for the UIView. If you see carefully at the end of the screenshot, the UILabel's text seems to overflow past the UIView.
I suspect that because the UIView cannot "capture" the size of it's subviews, the UIScrollView cannot calculate it's contentsize too(there's no reason for the scrollbar to work if its content view is only equal to one screen). Why is this happening even when the UILabel is clearly a subview of the UIView? If my suspicions are right, how do I set the UIView's height equal to the actual content size so that my UILabel is properly "contained" in it?
(Setting the UIView's height,width statically is not an option) .
NB: Tested the XIB without the UIView and only a single UILabel (with long text) inside a UIScrollView. Now scrolling works(since, I presume, the scroll view can calculate its content size).
NB2: I also tried the answers in this SO question and this post but my UIView simply wont extend beyond the dimensions of the screen. (I only care about horizontal scrolling)

AutoLayout issues are very hard to explain with text. I was having the same problem. I found the solution in this video. hope this will help you too.
https://www.youtube.com/watch?v=UnQsFlMGDsI
This video demonstrates how to create a UIScrollView which has some
views on the top of the screen and a view on the bottom of the screen
in Autolayout. UIScrollView content size is automatically adjusted to
the size of the screen or to the size of the content in such way that
on smaller devices scrolling is active and on larger devices scrolling
is not active because it is not needed. UIButton below UITextFields
always stays on the bottom of the screen and everything works on all
iPhone resolutions (iPhone 4 / 5 / 6 / 6 Plus).

Related

UIStackView within UIScrollView is cut off

I'm trying to use a UIStackView within a UIScrollView and I was hoping someone could point me in the right direction in creating the right constraints because I can't figure out what the problem is.
These are my constraints and ViewController structure.
So DestCont is a UIView that has a fixed height and ContentCont should take up the rest of the space, which could be (and is) larger than the screen so it should be able to scroll.
When I test it out in the simulator, I have the following problem. (Resized it so it would fit in the 2MB cap)
The green is the Root View and the black color is the ScrollView, as you can see, it cuts off the bottom portion of the ContentCont view.
EDIT
I changed the constraints, removed the fixed UIStackView height, but now, it doesn't show the bottom UIView that's in the UIStackView:
From your screenshot we know that you have set the StackView's height constraint equals to the self.view's height. Then the height is fixed(equal to one screen's height), even though its content view's height may be larger than the screen.
And UIScrollView will calculate its contentSize depending on its content, so in your case its contentSize's height will always be one screen heigt.
Delete this height constraint, let the ContentCont's content decide the height of it. Also please make sure your constrains in your ContentCont are correct.
I ended up with being fine that just my "ContentCont" UIContainerView will scroll and fixed the switching by using the following tutorial: https://spin.atomicobject.com/2015/09/02/switch-container-views/.

UIScrollView Vertical Scroll + Autolayout

I want to do something simple, yet Apple loves to overcomplicate things for developers (quite ironic). I want to create a vertically scrollable screen. Basically a longer screen that I can scroll through. The problem is that it either doesn't scroll or the content (a label for demo purposes) is fixed on the screen (e.g. centered).
I looked at multiple tutorials but still didn't fully understand it because the inner workings aren't fully explained.
So from what I understand, it goes the following:
You place a UIScrollView on top of the main UIView
You set the UIScrollView's margins to 0-0-0-0
You place a content view UIView inside the UIScrollView
You set it's margins to 0-0-0-0 related to both the main UIView and the UIScrollView
You set the UIScrollView and content UIView's height & width (in my case I chose 1000 for height and screen width for width since I want only vertical scroll)
You set the UIScrollView.contentSize to something bigger than the screen
You add the content and align it to the content UIView
So what am I missing or adding when I shouldn't? If anyone can explain how this is done quickly, please do so.
Quite a lot of this is wrong:
So from what I understand, it goes the following:
You place a UIScrollView on top of the main UIView
You set the UIScrollView's margins to 0-0-0-0
You place a content view UIView inside the UIScrollView
You set it's margins to 0-0-0-0 related to both the main UIView and the UIScrollView
You set the UIScrollView and content UIView's height & width (in my case I chose 1000 for height and screen width for width since I want only vertical scroll)
You set the UIScrollView.contentSize to something bigger than the screen
You add the content and align it to the content UIView
There are various strategies for making a scroll view scrollable under auto layout. The "content view" strategy is perfectly valid, and very convenient, though it is not the only possible strategy. Since you seem to imply you want to use it, let's use it:
Pin the scroll view's top, bottom, left, and right with constraints to main view. Typically these constraints will have a zero constant, but no law requires this.
Give the scroll view exactly one immediate subview, a "content view". Pin the content view's top, bottom, left, and right with constraints to the scroll view. These constraints must have a zero constant.
Give the content view height and width constraints. Set their constant values absolutely. Experimentally, use large numbers. As you've said, width of zero and height of 1000 will give you vertical scrolling on a screen smaller than 1000 height.
Now stop. Don't add any more constraints, and don't set the scroll view's content size in any other way. You are finished. The scroll view is now scrollable, even though there is nothing visible inside it — provided the height or width constraints constant values are larger than the actual height or width of the scroll view at runtime. And you can run the project and see that this is true.
You are now free to populate the content view.
You don't have to put a UIView inside the scroll view. You can just add whatever objects you want and set objects frame within the scrollview. The scrollable area is set by the contentSize property of UIScrollView.
Some things you will want to make sure to do:
1) Add <UIScrollViewDelegate> to your .h file
2) set scrollview.delegate = self;
3) Set scrollview.contentsize = CGSizeMake(something bigger than the screen)
4) make sure the scrollview is scrollable with scrollview.scrollEnabled = YES;

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.

UIButton inside UIScrollview not resizing with UIScrollView even after adding the constraints

I am facing a weird issue. I have implemented custom UIButtons as a Tile View in a UIScrollView which is added to superview. It is like there are six buttons, set of two placed sideways, and next set of 2 below them and so on. Now for implementing it to fit all iPhones Screen Sizes, I have added proper constraints to UIScrollView and constraints to UIButton relative to each other and UIScrollView. I have added #2x background images to each of the button with resolution as 320 *320. I have not provided any heights and widths constraints to them, so that they stretch freely according to different screen sizes.
xib has been initially designed as a 4" screen size. UIScrollView frame is stretching, however button remain positioned as in an iPhone 5S xib, hence it is looking improper on screens like iphone 6 etc.
What is the exact problem here?
See the work done here and confirm if this is correct. I have added constraints required to make the buttons looks proper in all devices.
here is the link
https://github.com/mahesh-agrawal/Test-Buttons-Inside-ScrollView

UIButton under UIScrollView not responding to touch

I am facing a very strange problem. Trying to implement constraints to my view controller makes my button inactive.
My view hierarchy is
UIVIew
UISCrollView
UIView
UIView
UIButton
There are many other views but just for simplicity. One thing is that there is an UIImageView object, which I am stretching to the view according to size but not objects are overlapping or similar, but might be related.
Basically all the constraints are in storyboard. Only for the image view I am using manual setting.
self.imageViewHeight.constant=imgHeight;
when I disable auto layout the button works just fine.
EDIT: Latest observation :Just found out that simulator iPhone 6+ works fine with the constraints. The same is happening with a similar view, which is smaller so all iPhone works just 4S.
So it is definitely issue related to screen size and manipulating with constraints.
Looks like all objects that are bellow screen view itself after creation, so you have to scroll it to see them are inactive.
Any help will be greatly appreciated.
It seems you need to increase the frame Width or Height (whatever you need) of container view. The contentSize of scrollView only affects how it will scroll, which is irrelevant here.
If the button is outside the container view, it will still show up. However, it can't respond to any touch event.
HERE WHAT WE NEED TO DO FOR TOUCH RESPONSE
All you need to do is set bunch of constraints for CONTAINER VIEW of scrollview. Start from adding leading, trailing, bottom, top, width equal and height equal. Now in my case, I need fixed contentSize of Scrollview, so i change priority of equal width constraints to 750. For dynamic contentSize, you need to set priority programmatically.
Comment below if you have any query..
Thanks

Resources