Constraints inside Scroll View - ios

I'm working on application for iOS. Trying to use Autolayout with Scroll View.
But there is some problem. I have View -> Scroll View -> Content View hierarchy. I pinned (top, bottom, left, right) of the Scroll View to the Main View, and also pinned Content View to Scroll View.
Then i've added imageView on the top of the screen and text label below, to the Content View. Added them constraints including vertical spacing (8pt) from image to label. In Preview everything looks ok and label placed right below image, however when i'm running the app on iOS Simulator, my label places right in the middle of image. Please, any help?

We found an answer in the comments: it was due to a wrong content scaling mode of the image. It needed to be ClipToBounds.

Related

Extra white space at bottom of UIScrollview

My Scroll View is pinned to the safe area on all 4 sides and is the size of the screen. I pinned the content view (view inside scroll view) to the content layout guide of the scroll view. And all my UI elements in the view are constrained properly so scroll view height ambiguity is not an issue. However the user can scroll down the continue button, and I don't know how to solve this issue.
This is the error I'm having:
Image for Extra space beneath content view inside scroll view
Another image. This causes white space beneath the blue view as so, I want the user to not be able to scroll past the blue view.
To make the button be fixed at the bottom of the view, then:
make sure the continue button and blue view are not inside the scroll view
constrain the blue view to the main view's bottom constraint
constrain the scroll view's bottom constraint to the top of the blue view
This way, the button will remain fixed, while the content within the scroll view will still be scrollable

Scrollview not working properly on iPad in xcode(iOS)

Recently, i've been building and app which requires a scrollview, for all the content to fit. I've had a few difficulties creating my scrollview. I've tried a few different methods for building it, but ended up building it in storyboard with autolayout. I've set the height of the view controller to 1000, and therefore also the simulated size to freeform. The width of the content view inside the scrollview, I've to the same as the view which contains the scrollview.
The hierarchy goes like this:
-View controller scene
-Top layout guide
-Bottom layout guide
-View
-Scroll view
-Content view
-Label with text here
-Constraints
-And so on
I've been replicating the process in this link, to create the scrollview:
https://www.ralfebert.de/snippets/ios/auto-layout-recipes/uiscrollview-storyboard/
When running the application on the simulator, I get the following result:
The scrollview is not working properly on the iPad. It seems like the scrollview doesn't adapt to the changes in the width, which happens when its ran on an iPad, since it's bigger. When the app is ran on the iPad, the scrollview stays the same width as if it were shown on the iPhone.
This is how it looks in the editor. The view controller on the left is the view controller which has the scrollview implemented, and the one on the right doesn't. The first image shows the storyboard, when I view it with the iPhone 8, and the second image is when I view it with an 9,7" iPad:
It would be greatly appreciated if anyone could give me a hint to whats going on!
EDIT:
Left side is what it looks like, and right side is what it should look like:
Add the UIScrollView to your main view
Set Top, Left, Right, Bottom constraints all to Zero
Add a UILabel inside the scroll view
Set number of lines to Zero
Set Top, Left, Right, Bottom constraints all to Zero
Set the label's width constraint equal to the scroll view's width
That should do it :)
This will keep the label's text aligned to the top of the scroll view. If you add enough text to fill more than the full screen, it will scroll vertically.

Setting the content size of a view inside UIScrollView

I have to lay out a few views in a View Controller which should look like this when run.
Initially the white view should be partially covering the blue view at the bottom like shown in the image. The blue view should stay put while the white view at the bottom can be scrolled over the blue view.
I added the blue view to the main UIView of the view controller. Then added a UIScrollView on top of blue view and added the white view on to the scroll view.
Now I'm getting the dreaded ambigeous content size error. I have pinned the scrollview on all four sides. Then added leading, bottom and trailing constraints to the white view. Then I tried adding a top constraint to the white view but the error still persisted. I also adding a height constraint to the white view to no avail.
It might be dofficult to imagine my setup so I added a demo project here as well.
I set the constraints for you here.
Explanation:
You are getting ambigous content size because your scrollView does not know its content (white view's) width and height.
I added top,width and height constraint to white view. This way your scrollView knows its content width and will scroll only vertically. As for content height - u can change heightContstrait's constant in code, or completely remove height constraint if you use autolayout properly for white view's subviews.
Put the blue view under scrollview. And set scrollviews content inset, to make your white view appear not on top, but with some space. Now on start you get white view a bit over blue, and on scroll it covers blue view. About size errors, scrollview needs to know it’s content size initially. I assume your white view is table view, so set it’s bottom constraint to zero. If you want blue size to change it’s size on scrolling, like it’s avatar or something, it’s a bit different. You should take scrolling events on uiscrolldelegate, and change blue views height accordingly
Make sure you've read (and understand) Apple TN2154: "UIScrollView And Autolayout", which explains the steps required.
Looks like you're not specifying the content size properly.

Parallax header on a one-page screen in iOS using Interface Builder

In an iOS 8 app, I'm trying to create a screen that has a "parallax header", i.e., an image header that grows as you pull down. I would like to do this using only constraints in Interface Builder, if possible.
Here is a nice guide by Pete Hare on how to do such a thing, and I've also had good help at looking at this example project by Bill Carson. However, contrary to these projects, this is not the header to a scrolling area that's taller than the screen, like a Table View; it's just one page. And for some reason, I can't get things to work in my app. I find Scroll Views in Interface Builder rather confusing to begin with. Could anyone walk me through the steps?
Why, certainly! First we'll set up a view controller with a scroll view.
Create an empty View Controller. Give its initial View the Xcode Specific Label Root View so we can tell things apart.
Add a Scroll View. Resize it to fill the view controller, and add constraints for Leading, Trailing, Top and Bottom to equal the superview's corresponding edges. (I do this by control-dragging from Scroll View to View in the Document Outline, hold down the Option and Shift key and then select all four edges, and then Add Constraints.)
Enable Bounce Vertically in the Scroll View's Attribute Inspector.
Add a simple View to the Scroll View and pin its edges to its superview -- the Scroll View -- in the exact same way as we did with the Scroll View to Root View (although this time we don't need to hold Option key when adding constraints). Give the new view the Xcode Specific Label Scrolling Content.
Xcode is not happy, it says Scroll View is missing constraints: "needs constraints for X position or width" and "needs constraints for Y position or height". Let it automatically add missing constraints, it will add constraints for the center of Scrolling Content to the center of Scroll View, in X and Y directions.
By setting a background color to the Scrolling Content, we can now run and confirm that the scroll view with vertical bounce is working as intended. Nice. Now, let's add the header.
Add a nice header image to the project assets, and drag an Image View to the Scrolling Content. Label it Header Image. Select your image asset as the Header Image's image. Drag the corners of the Image View so that it is aligned to the top, left and right edges of your view. Now let's go through the constraints to set on the Image View.
We want the top edge to be fixed to the top of the screen, regardless of how the user is scrolling. So we need it to be pinned to something outside of the Scroll View. You may try fixing it to the Root View's top edge, but unfortunately, that does not work for some reason. What does work is to pin it to the Top Layout Guide. You'll do this easiest by control-dragging in the Document Outline, between the Header Image and the Top Layout Guide and accpet the suggested constant.
The bottom edge of the Header Image needs to be pinned to something inside the Scroll View. Ultimately, we'd like it to be set to a fixed distance from the top of the Scrolling Content -- but Interface Builder won't let us do that. You can only set it to some distance from the bottom of the Scrolling Content, which is not very practical since you will then have to take the height of the device into account. What we instead do is to add another view directly beneath the Header Image, pin that view's top edge to some distance from the Scrolling Content's top edge, and then pin the Header Image's bottom edge to our new view's top edge. This could be a regular View that holds the rest of your user interface below the header. But for this example (and to demonstrate a later point in this guide), we'll use a label. Add a label directly beneath Header Image and give it three constraints: pin it's top edge to the Header Image's bottom edge, it's top edge also to the Scrolling Content's top edge, and it's center X to the Scrolling Content's center X. The distance between the label's top edge and Scrolling Content's top edge will be the height of the image in the non-dragged state. This unfortunately needs to be set to a constant in the storyboard file -- we'll have to update it programmatically. More on that later.
The last part is easy: pin the leading and trailing edges of the Header Image to the leading and trailing edges of the Scrolling Content.
Now, all our constraints are in place! If you run the app, you can see how it's working correctly constraintwise, but the image isn't scaling the way we expect it to. A couple of last tweaks before we're done.
In the Attribute Inspector, under View, set the Mode of the Image View to "Aspect Fill". That gives it the correct parallaxy behavior.
To set the height of the Header Image correctly, we need a little bit of code. First, make an outlet from the constraint between the label's top edge and the Scrolling Content's top edge -- the one we set to a fixed value -- to your View Controller's source file. Call it imageHeightConstraint. Also add an outlet from the Image View called headerImageView. A good place to update the constraint programmatically is in the viewWillLayoutSubviews View Controller delegate method. Here is some code in Objective C:
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
CGSize imageSize = self.headerImageView.image.size;
CGFloat heightForWidth = imageSize.height / imageSize.width;
CGRect screenBounds = [UIScreen mainScreen].bounds;
CGFloat screenWidth = CGRectGetWidth(screenBounds);
self.imageHeightConstraint.constant = screenWidth * heightForWidth;
}
Finally, you may notice that when scrolling up, the label -- or whatever content is underneath the header view -- is getting covered by it. This is solved by checking Clip Supbviews on the Image View's Attribute Inspector.
Whew!
(Note: I began writing this as a question and then kept writing while I solved it for myself. I guess it would do well with a little text pruning and some images, but maybe it will help someone...)

Gap between main view and scroll view using Auto Layout in navigation controller

I'm experiencing some trouble managing a scroll view embed inside a navigation view controller. I'm using Auto Layout and I'll try to explain the problem the best I can.
I embed a scroll view in the controller's main view and pinned the top, left, bottom and right borders to main view's borders.
I embed a standard UIView inside the scroll view and gave it a fixed height of 800 points. This should act as a container for all my controls (let's name it content view). Then again I pinned its top, left, bottom and right borders to the scroll view's borders. Because the bottom space constraint of scroll view's descendant view was negative, I adjusted it bringing it back to 0.
For the width, I CTRL-dragged from the content view to the main view and added a Equal widths constraint.
Finally, I added an image view and placed it at the top center of my content view adding some further trivial constraint.
The storyboard for the situation I've just depicted is shown above (in the document outline you should see all the constraints I've defined).
My scroll view works, it scrolls fine and the image view is well-centered where it's supposed to be. However, there's a gap between the end of the navigation bar and the start of the scroll view and I can't figure out why. It seems to be as high as the navigation bar, but I have no idea about how to fix it. The image shown below should make you understand what I'm talking about (the content view is highlighted in grey for clarity).
I didn't write a single line of code to achieve this result. I would really appreciate any kind of help and I'm ready to give you all the information you need to help me address the problem.
I think you should uncheck Adjust Scrollview Insets property of your viewcontroller to get rid of this....
you have to uncheck Adjust Scrollview Insets

Resources