Autolayout reseting views after changing frame in code - ios

I am trying to change some frames inside the code but I want autolayout to be respected.
I have this hierarchy
When I hit the search button on top right of navigation bar, I want the green view to go up 50px. It is working great but the tableView is not following the autolayout since its top is binded on the green view.
So when I hit the button I have a blank space between the navigation bar and the table view.
Any ideas how can I sort this out using autolayout?

When using auto layout, frame is dynamic based on constraints. Each time the view layout, it will recalculate by constraints and update view's frame. So instead of changing the frame of green view, you should change corresponding constraints.
Make a constraint reference in code call topSpace which is the constraint between green view and top layout guide and set its constant to -50 when user tap the button.

Related

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.

Autolayout with a dynamic UIView in a ScrollView

I'm using a mix of Xamarin and XCode Interface Builder to build my UI.
As you can see in the screen shots the PlaceholderView at the top can have different content. The problem I'm having is trying to keep the Submit button at the bottom of the ContentView.
I'm using the ScrollView with ContentView approach and setting constraints in IB.
In ViewDidLoad() I load the contents for the PlaceholderView and then I set the height constraint of the PlaceholderView programmatically.
public override void ViewDidLoad()
{
onlineSuspectDetails = OnlineSuspectDetailsView.Create();
onlineSuspectDetails.BackgroundColor = UIColor.Gray;
SuspectDetailsPlaceholderView.AddSubview(onlineSuspectDetails);
SuspectDetailsPlaceholderView.HeightAnchor.ConstraintEqualTo(onlineSuspectDetails.HeightAnchor, 1).Active = true;
}
Now of course I had to set a Top and Bottom constraint for the Submit Button so it's working for one type
but I can't see a way to change it depending on height of the PlaceholderView in order to keep the Submit Button at the bottom.
If I could access the Bottom constraint I can calculate the new Top constraint but I can't find a way to access the Bottom constraint. How can I do this?
Are there any alternative suggestions to how I can solve this problem?
Hmmm... a bit tricky...
There may be better ways to do it, but here is one approach:
Orange = main view background
Pale Yellow = scroll view background
Gray = UIView... "label / field pairs" container; label/field pairs are in a standard UIStackView
Cyan = UIView... "details" container
Dark Green = button
Red = UIView... this is the tricky part... is a "Shim" to hold the button at the bottom
View constraints are inset by 8 so we can see them easier than if they're taking up the full screen/view.
Gray view and Details view constraints for positions / sizes are straight-forward (looks like you have no problem with that aspect).
In this method, we use a "Shim" view, and some greater-than-or-equal-to constraints to manage the Button's position.
The Shim is pinned leading and top to Zero, and its Height constraint is set to >= -30 relative to the scroll view height. Its bottom constraint is also set to >= 8 relative to the bottom of the Details view.
This tells auto-layout to put the bottom of the Shim no more than 30-pts from the bottom of the scroll view AND at least 8-pts below the bottom of the Details view.
Then the top of the Submit button is constrained to the bottom of the Shim view.
One "quirk" that I've found when working with scroll views in Interface Builder - it can be really tough (maybe impossible?) to get IB to be happy with the necessary constraints. It will show conflicts, but if you follow IB's "fixes" the desired layout then fails.
I don't actually work with IB / Storyboards, so I just focus on avoiding auto-layout / constraint conflicts at runtime.
This is probably easier to understand by seeing the actual file, so I put this up as a GitHub repo: https://github.com/DonMag/SWMoreScrollViewStuff
How are you actually adding the button to the main view? I have done something like this before by having a master UIView for everything except the button. And then I just put the button below the view and applied auto layout to everything (should just be 0,0,0,0 on the view and button). This way your button is always at the front of your view and you can do everything else in the contained view!

Button is being covered by tabbar

I have a save button that is supposed to be located right above the tab bar and right under the table view, but it does not appear in the view when I switch to a smaller screen. There is auto layout on all the elements, and the button is centered horizontally, equal width to the view, and has vertical spacing between the table view and bottom. Any ideas on how to make sure the save button always appears in the position stated above? Auto layout was done through storyboard not code.
set height of UIButton, and do not set height of UITableView.

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

AutoLayout or not? How to position 3 subviews?

I can't figure out how to correctly position subviews in a Navigation Controller.
I am trying to position a view, table and another view.
If I turn off AutoLayout than top view and table are ok but my bottom view is pushed off the screen.
With autolayout I get both the table and bottom view in the wrong place:
I try to set frame in viewDidLoad as follows (calendarPicker is position at the top below navigation bar), I want the configPanel to be on the bottom, I hide bottom bar on Push.
self.eventsTable.frame = CGRectMake(0, CGRectGetMaxY(self.calendarPicker.frame),
self.eventsTable.bounds.size.width,
self.view.bounds.size.height - self.calendarPicker.bounds.size.height
);
self.configPanel.frame = CGRectMake(0, self.view.bounds.size.height,
self.configPanel.bounds.size.width,
self.view.bounds.size.height - self.configPanel.bounds.size.height
);
Should I rely on autolayout? How should I make my constraints?
I believe my problems arise due to autosizing of the table mostly, but given that I am setting its frame size why would it not change? I do not want to remove auto layout since it is used on other views designed in the storyboard and from what I understand it applies to all?
Is there something that I am missing that needs to be done on top of setting the frames of individual controls?
EDIT:
I think my biggest problem is autolayout and inability to size table appropriately. If I add constraint to the bottom view to be 0 from bottom of the view, it will originally appear correctly. However consequently when resizing table and top view, the table will push bottom view down sizing itself to occupy all available space.
I need to force UITableView to be no more than height between the bottom of the top view and lower view, but still not sure how to do this.
Somewhat closer
Removing code for frame change of the table fixes the issue of the bottom view being pushed off. However in this case top view overlapps table when it changes size at the same time not being drawn correctly:
Uncheck autolayout and then set frames of all three subviews.
Or
If you want constraints then you can use NSLayoutConstraint class to add constraint to your subviews.
I recommend against switching off autolayout, especially because you can't do it on a view by view basis. Autolayout is a must if you tend to do i18n or want to make sure your app does well in different screen resolutions/orientation.
Try This!
disable use Autolayout in storyboard. Place your three views on view controller(view1, view2, view3). Next go to size inspector and use autosizing masks for all three views. Check this, which will help you
http://www.raywenderlich.com/50317/beginning-auto-layout-tutorial-in-ios-7-part-1

Resources