Strange behavior of constraints, iOS8 - ios

I have two root views on superview.
All views and constraints I've added from code. Top view have H:|-0-[view]-0-|. Same vfl code have bottom view. Next, top view attached top to top, bottom to top of second view, second bottom attached to bottom. The code is V:|-0-[topView]-0-[secondView]-0-|.
Second view have intrinsic height, so height of both views depends on this value. When I change bottom view height and animate layoutIfNeed all works fine for me.
Next, bottom view have some subviews. Bottom is simple view-container and top is button. Both of them attached to left / right, like H:|-0-[view]-0-|. Bottom view has intrinsic height too, so vertically them attached like outside views, without (!) attaching button to top of superview (V:[button]-0-[secondView]-0-|). Second view is ATTACHED bottom to bottom, but when I animating changing height of this container, its subviews go top on iOS 8.
View hierarchy is
Constraints:
H:|-0-[topView]-0-|
H:|-0-[bottomView]-0-|
V:|-0-[topView]-0-[bottomView(110)]-0-|
H:|-0-[buttonBackCamera]-0-|
H:|-0-[grayView]-0-|
V:[buttonBackCamera]-0-[grayView(85)]-0-| //here is constraint, that MUST attach grayView to bottom.
While debugging, I noticed, that constraint is attached, active and it must work, but :( .
Any thoughts about this?
UPDATE
I've checked this on iOS 8.3, all works fine too.

Make sure bottom view contains constraint from Leading to superview, Trailing to Superview and Bottom to Bottom Guide.
And if you are still facing any issue then go for,
-(void)viewWillLayoutSubviews
{
[self.view layoutIfneeded];
}

I don't think I got the problem entirely but may I suggest you to check the size class that is selected and the size class for each of the enabled constraint.

Related

iOS - UIScrollView not scrolling, though scroll bar is shown

I have a Scroll View, and inside it a UIView called "Content View", that contains all of my elements.
The Content view is equal to the Scroll view's top, bottom, leading and trailing. Also equal its width & height.
I also added self.scrollView.contentSize = self.contentView.frame.size
in ViewDidLoad.
When I scroll I can see a scroll bar going up and down on the side, and it seems like the page length is correct according to the bar, but the content itself does not scroll as you can see here:
What am I doing wrong?
Thanks!
I ran into this issue (or something very similar) where the scrollbar would scroll, but the content did not. It drove me crazy for a while because it seemed like everything inside of the scrollview was constrained correctly in Interface Builder. Finally, I noticed that the top item within the scrollview container (container = the view inside of the UIScrollView that contained all of my views) was constrained to the top by aligning with a view outside of the scrollview.
Once I removed the constraint that was aligning the top with an external view from the ScrollView and instead aligned it with the main container within the UIScrollView, everything worked fine. Hopefully that helps in case someone runs into this issue and the other mentioned solutions don't fix it.
The Content view is equal to the Scroll view's top, bottom, leading
and trailing. Also equal its width & height.
You need to remove the width and height constraints. Top, bottom, leading and trailing should stay. Also, remove that contentSize setting from viewDidLoad.
I assume you want vertical scroll. In that case, you should set contentView's width constraint to be equal to View's width (not scrollView's but View's which is the root of the hierarchy).
That should do the trick, assuming that vertical constraints of contentView's children are properly set up.
By default Content Layout Guides is enabled for a Scroll View. So when we pin the content view (main view inside the scroll view) on all 4 sides and equal width and equal height (with lower priority), it takes Frame Layout Guide for top constraint, this is the root cause of the issue where only scroll indicator moves and not the entire content.
You can uncheck Content Layout Guides from Scroll View Size Inspector. Or if you want to use it change the top constraint to Content Layout Guide instead of Frame Guide Layout and it worked as charm. Please refer below screenshot.
The 1st thing I had to do is what user3199693 said: remove that line from viewDidLoad (that made the wrong scroll bar I saw to go away). Also I set contentView's width constraint to be equal to top View's width, as he said.
That was good, but still didn't solve the problem. What did help was equal the height of the content view with top view.
Got the idea from here.

Autolayout with UIScrollView

I am using autolayout in Xcode and am creating a fairly tall (1300px) ViewController with a uiscrollview to navigate up and down. I made the viewcontroller freeform so its dimensions are [375,1300]. I then incorporated the scrollview, added the content view as well as all the subviews & constrained everything, leaving no constraint errors. At runtime there are no errors, but everything is all smushed into the normal screen size when I intended for it to be very tall (~1300px) and scrollable. Any clue as to what I am doing wrong?
Below is a diagram showing the issue where:
The Outer Black Blox is the ViewController's view
The Inner Black Boxes are subviews
and The Blue Box is what is displayed on the screen
Yes, your correct #Ryan Cocuzzo. I think you need to set sub view priority from 1000 to 250. See below screen shots.
1) Select height constraint of the subview
2)Then go to show to size inspector
3) Now change the priority constraint from 1000 to 250.
4)Finally you get like this
Make sure the following are true:
The 4 content views are subviews of the UIScrollView, not your view controller.
The autolayout constraints on the 4 content views must reference the UIScrollView only, not the view controller's view.
The 4th box cannot have a bottom constraint.
It looks like the 4th box has a constraint to make it's bottom align with the bottom of the view controller's view. This would force the other views to smush up together. The 4th box also cannot have a bottom constraint so that the scrollview can resize itself to encompass it's subviews.

Setting UIScrollView Width

I have a UIScrollView added to my ViewController. And a View on top of that Scrollview. I have done the following:
Placed scroll view inside my original View and set top, left, right, and bottom constraints. Unchecking Constrain to margins.
Added a UIView within the scrollView (to hold my labels and such) and added the top, left, right, and bottom constraints, constrain to margins unchecked. And set equal widths to the original View
I then add an image view and three labels inside the view placed within the scroll view. And add top, left, right, bottom, and height constraints for them.
The scroll view works and my view does scroll and my labels and image view are centered but everything is very wide.
I am wondering how I make it so the View is not wide and I cannot scroll horizontally, only vertically.
Add an equal-widths constraint between the view inside the scroll view, and the root-level view of the view controller.
I just recently figured this out. Try doing this:
Make a scroll view
Put all of your labels and buttons into a stack view (If you don't know about stack views, check this out: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIStackView_Class_Reference/
Constrain the stack view's width and make sure the Allignment and Distribution are set to fill
Put the Stack View inside of the scroll view
Constrain the Scroll view to your hearts desire
Putting the labels and what you want in the scroll view should help with the width boundaries. Here's a picture of my successful scroll view. Hope this helps :)
In short, the contentsize is no effect while you use autolayout.
if you want you scrollview can scroll, uou should add a container inside scrollview and add origin subviews to the container.
For example, use snapkit (maybe some typos here):
you have a scrollview.set it's equal self.view's frame by autolayout
[import]then you add a containerView as scrollview's subview. set contraints:
make.edges.equalTo(scrollview) // mean its frame equal to scrollview
make.width.equalTo(self.view) // set width equal to self.view
make.height.equalTo(yourheight).priorityLow() // the actual height,if no changes,you can ingore .priorityLow()
add your sunviews to containerView,add the contraints must set to containerView,can't set to scrollview's.forexample,:
containerView.addSubView(myview)
myview.snp_makeConstraints { (make) -> Void in
make.left.equalTo(self.containerView)
make.top.equalTo(self.containerView)
make.right.equalTo(self.containerView)
make.height.equalTo(267)
}
Read this official doc -
Technical Note TN2154 UIScrollView And Autolayout.

Implicit Constraint iPhone Portrait Screen Height

I tried to create a custom freefrom view with interface builder.
I have a UIView which is containing a UIImageView and UILabel.
I set the constraints to adjusting the Label according to the Image etc and a margin to the superview.
Now I want the superview to exactly fit the subviews. But when I press Editor -> Size To Fit Content, the superview is not resized completely and the constrains are in conflict. What there appears is a implicit constraint ("iPhone Portrait Screen Height"), which can not be altered/deleted. See Screenshot below:
While not ideal, depending on how your XIB is structured and how you are referencing the view, you could create a "scratch pad" view and place your custom view inside of that just to see how everything will layout. That is if you're setting the view to an outlet defined in the XIB's File Owner, you can just connect it to the view you've created inside the "scratch pad".
For example, I created a container view with a square and a switch inside. The top example complains of conflicting constraints and doesn't layout correctly, while the bottom example shows the same thing centered in a throw-away view. Again, not ideal, but it's working for me.
Edit: I just realized that some size class constraints may be lost once the "scratch pad" view is discarded so that is another wrinkle to consider. Still looking into this.
Just to make it simple forget the label for the time being. You have already added the width and height constraint of the image view, now instead of using sizetofit content, try adding leading, trailing, top and bottom constraints between the image view and it's parent view. With that your parent view should fit the image view.
The same technique (constraints to parent view) can be used to get it work with the image view and label together.
I noticed that when I physically dragged the superview's width and height to satisfy the constraints, the red constraint errors went away along with the "iPhone Portrait Screen Width" constraint. In other words, my constraints dictated that my subview be bottom aligned with its super view. If I dragged the superview's bottom edge up to align flush with the subview, the errors went away. Still seems buggy and unintuitive.

Aling UIView to a UIToolbar using autolayout

I trying to align an UIView to the bottom of a container view(UIScroolView) and above a tool bar.
It works perfectly when design to the iphone 3.5 display but when a change my layout to the 4.0 display, my view doesn't get alined to the bottom instead it stays in the same position with a gap from the UIToolbar.
I checked and i realized the i have a constraint Vertical Space with a constant and i think thats why my view always stays in the same place, the problem is i can't get rid of this constraint, i'd like to know if someone could help me with this one.
thanks!
I think you need to add a height constraint to the toolbar. If you have that and a zero length vertical spacing constraint between the toolbar and scroll view, you should be able to delete that constraint to the top of the super view.

Resources