Adding ScrollView to ViewController with 2 custom Views - ios

My viewController has one view with images and labels and one textView
Im new in objective c.
My problem is to add ScrollView in my ViewController with 2 custom views(UIView and UITextView).(image in the link) I have tried many things posted here in Stack but nothing works for me.
Thank YOU!
Here is what i have :
self.scrollView.contentSize=self.scrollView.frame.size;
self.scrollView.frame=self.view.frame;
[self.view addSubview:self.scrollView];

Adjusting view's frame was the technology of 5 years ago. You should never set the frame manually, not anymore. Instead start learning Autolayout and Constraints.
These tutorials may help:
https://www.raywenderlich.com/115440/auto-layout-tutorial-in-ios-9-part-1-getting-started-2
https://www.appcoda.com/auto-layout-guide/

You are setting the content size equal to the frame size before you actually set the frame, so it's probably just 0.
You need to just switch the calls around:
self.scrollView.frame=self.view.frame;
self.scrollView.contentSize=self.scrollView.frame.size;
[self.view addSubview:self.scrollView];
The other thing to keep in mind is that because you are setting the frame of a nested view to the frame of its superview, your layout will break (or at least not do what you expect), if the origin of your superview ever changes. If the origin is 0, 0, then you are fine for the moment, but otherwise you may want to set the subview (scrollView) frame to be equal to the superview (self.view) bounds instead of the frame, like this:
self.scrollView.frame=self.view.bounds

Related

UIView position does not respect NSLayoutConstraint when altered from viewDidLoad

I have two views, one visible (grey) and one hidden (red). The visible view is constraint to the superview top with a constant of 32, and the other constraint to the superview top with a constant of 16.
The top of the visible view is also constrained to the bottom of the hidden view, with a constant of 8. This constraint has a priority of 749, because it is initially unsatisfiable.
The idea is that the visible (grey) view should be 32 points below the superview normally, but when the hidden (red) view is made visible, the original (grey) view should be 8 points below the other view (red).
I'm achieving this by keeping a strong reference to the 32-point constraint, and making it active/inactive as I'm hiding/unhiding the view (red).
Here's a picture of my layout:
This works very well normally, but I've been trying to set constraint.active = NO and redView.hidden = NO in viewDidLoad, as I need the textfield to display an error if a certain condition has not been met. For some reason, this does not work. The red view is displayed as expected, but the second view (grey) does not move down as it should (it does not respect the 749 constraint, even if the main constraint is no longer active). Here's a picture of the result:
However, I made the code to inactivate the constraint and display the view run after a small delay (using dispatch_after();), and then it suddenly works as expected:
My question is: why doesn't the view respect the constraint and move down when it is run immediately from viewDidLoad? Why does it suddenly work after a small delay? Is this a decent solution of achieving my goal, given I can get it to work properly?
call it in viewDidLayoutSubviews methode not in viewdidload.
autolayout it take some time to load so call it in viewDidLayoutSubviews.
While using autolayout - (void)viewDidLoad will return the frame which you gave in storyboard.
You have to use - (void)viewDidLayoutSubviews to update the frame according to constraints.
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
//Replace self.view by your view whose constraints need to update
[self.view layoutIfNeeded];
}

UIScrollView not scroll auto layout issues

I never used auto layouts in my life and it was great time, now storyboard take off my brain.
The conception maybe is not bad. But it's still buggy and worst to use. I have worked for today and spend 8 hours to setup one scroll view and few subviews. Does it save time???
If Apple wants to support adoptive design. Why they don't use Edge Reflow conception. It is for web, but it's great and without bugs....
I have scroll view with all needed constraints, it means that the scroll view size will be the same as superview.
I am trying to change scroll view content size in -viewDidLoad method:
[self.theScrollView setContentSize:CGSizeMake(self.view.frame.size.width, 20000)];
but seems it want work.
Print out says that the content size is 320 20000, but I can scroll it.
With autolayout, you have to do things bottom-up and implicitly; in other words, instead of telling the scrollView how big its content is, you let the scrollView adjust itself based on the size of its content. This allows the autolayout to resolve the constraints between subviews and propagate the changes upward.
If you want to explicitly set the content size, you could create an additional subview containing all the content of the scrollView, and then override its intrinsicContentSize method to explicitly tell the scrollView how big it is.
Working tried out.
if you are not using autolayout then put it only viewDidLoad():
[_mainScroll setContentSize:CGSizeMake(320, 2000)];
or if you are using autolayout then follow this:
First give constrains to scrollview top,bottom,leading and trailing.
Now take one more view and give same constrains as scrollview given by you earlier.
Don't forgot to give additional constrain for that view fix height and width equal to main parent view.
or
Just watch this.
https://www.youtube.com/watch?v=rjTS9fyWqdg

iOS: Getting height of views with programatically added constraints as only indicator

Hello there fellow iOS programmers. While creating an app I've ran into a problem I can't seem to find an answer to. Let's lay it out:
I'm creating a UIViewController with a UIScrollView as it's only child. Inside this view I have a UIView, and inside of this there is a list of UIViews with UILabels inside them. As you all know you need to specify a contentSize for a UIScrollView.
The problem is that the list needs to be dynamic with it's content, and I therefore have no way to know the views heights beforehand. I'm adding all views with constraints where the height is set to ">=0".
When I later try to set the height of the UIScrollView I need to either get the height of the UIView that the list is inside, or get the origin.y and height of the last view in the list. This of course needs to be ready by the time the view is displayed to the user.
I've currently tried view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize), which returned 0; view.systemLayoutSizeFittingSize(UILayoutFittingExpandedSize), which returned 10000; and view.origin.y + view.frame.height, which also returns 0. It seems to me like the constraints haven't taken effect yet.
I've tried setting both constraints and UIScollView.contentSize from viewDidLoad(). I've also tried to set constraints in viewDidLoad and setting contentSize in viewWillAppear; this yielded the same results. Setting constraints in viewWillAppear and setting contentSize in viewDidLoad only caused a crash.
Bottom-line: When should I set up the UIScrollView.contentSize if I want to get view.height or similar methods to return a correct result, while at the same time be ready by the time the user sees the view?
Btw, I'm making this app in Swift, so answers in this language is preferred, but I'm able to translate from Objective-C to Swift; post in whatever suits you best.
Thank you! :)
You say:
As you all know you need to specify a contentSize for a UIScrollView.
No, as TN2154 says, the constraints between the scroll view and its subviews are "interpreted as the content size of the scroll view" (emphasis added). This is a boon, because you no longer have to mess around with contentSize if doing auto-layout. Just set the constraints for the scroll view's subviews and the content size takes care of itself. This leverages the labels' intrinsic size (and make sure that the label's numberOfLines to zero).
The only trick is that it sometimes cannot figure out the correct width of the labels (because the trailing constraint is to the scroll view's content size, it will sometimes make the scroll view a horizontally scrolling one). You can remedy this by either manually setting preferredMaxLayoutWidth or by setting a width constraint between the label and the scroll view's superview.
Personally, while I understand the inclination to add the UIView containers between the scroll view and the labels, I'd suggest losing them unless you need them for some other reason. IMHO, it simply complicates the constraints unnecessarily. It's hairy enough as it is. Obviously, if these containers bear other utility for you, then go ahead and keep them (and they'll work fine), but if you're doing this simply for the sake of the constraints, you might consider eliminating them.

UIScrollView using Autolayout will only bounce

I am really struggling to get a UIScrollView to work correctly with Autolayout. Instead of scrolling down as it should, it just bounces, so if I drag it to see more as soon as I let go it returns to its original position.
I have my scene set up in the following way:
-Main View
- Scroll View
- Content View
- Label
- Label
The View Controller has its size metric set to Freeform. The Main View, Scroll View and Content View all have their Height set to 700, so I can see the layout correctly.
In my .h file I have an outlet connected to the UIScrollView and in my viewDidLoad method I am doing the following:
Scroller.translatesAutoresizingMaskIntoConstraints = YES;
[self.Scroller setContentSize:CGSizeMake(320, 1000)];
I've tried setting all sorts of constraints, on various things. Normally when I add a new one Xcode then grumbles that the constraints are incorrect and prompts me to update them. I have tried so many different variations, I can't remember them all but here are a few:
Pinning the height of the Scroll View
Pinning the bottom of the Content View to the Scroll View - Getting UIScrollView to work with AutoLayout
Pinning the height of the Content View
Other things I have tried:
Reading & following Apple's Technote: - https://developer.apple.com/library/ios/technotes/tn2154/_index.html
Setting the ScrollView's Content Inset - Confusion Regarding UIScrollView and AutoLayout
Setting the Content Size: UIWebView's UIScrollView subview can scroll but bounce back to the frame without appearing vertical scroll indicator
I'm sure this must be relatively straight forward, but I have been tearing my hair out. There are many similar questions on Stackoverflow and Google, but none of them seem to fully meet my requirements.
Any help or resources would be greatly appreciated.
JA
One possible reason for this is that scroll view's contentSize is reset after layout event which happens after viewDidLoad (for example due to incorrect constrains settings).
I had to put the code in viewDidAppear for it to work right
CGSize size = CGSizeMake(320, 931);
self.scroller.scrollEnabled = YES;
self.scroller.contentSize = size;

Is it possible to get the calculated frame given an array of constraints?

I'm trying to animate a view from a thumbnail to a fullscreen view when touched. When the view is in thumbnail mode it is a subview of the UITableView.tableFooterView. When I animate to fullscreen I move the view to the controller's root view before updating the constraints. I do this because the tableview clips the subviews.
This is working perfectly, but when I try to do the reverse animation it's not so easy. I have to first move the thumbnail view back into a subview of the UITableView.tableFooterView before I can update the constraints. I then undo the constraints (basically set them to what there where originally). This works but the animation does not look right because as soon as the view is moved back into UITableView.tableFooterView it's clipped again by the UITableView and the animation is partially hidden behind all the tableview adornments!
My idea is to get the calculated frame for the constraints and perform old fashioned frame animation and then install the constraints after.
Is there a known way to ask the layout system given an array of constraints what will the frame be without actually installing those constraints?
Thanks.
I don't think there is such a way.
Note that the constraints you define (NSLayoutConstraint) are not the only constraints. Other constraints are defined by the properties of your views (e.g. intrinsic content size, hugging priorities etc.).
I guess this is something that would work better with autoresizing instead of autolayout.
Another solution would be to use a hidden placeholder view in the table footer. When you are returning the view back into the footer, you can just ask for the frame of the placeholder.

Resources