This is my view hierarchy:
I want to set height constraint for the View, but it doesn't allow me to set it in the storyboard, and when I set it programatically I got a runtime error (nil)
I went through your case in one of my project, which I needed to embed a view in a static table view. Yes, what different here is that IT IS STATIC, and you can create as many sections as you want.
What I did is really simple, you just need to adjust the view as you wish, then uncheck the axis that you don't want it to be auto layout.
For example, I wanted my view to fit with 44 as its height, and didn't want it to scale bottom down way. So I configed it as the picture bellow.
Hope it helps.
Related
I have view with three button with equal size. Each button take 1/3 part portion of view.
Like this image:
If I remove/hide one button then two button width should increase equally and take 1/2 portion of view. if I remove two button then one button size should be equal size of view.
My question is, how it's possible using the Autolayout.
Best option is using stackView. StackView gives lots of flexibility in adding or removing items. If you wish to use only auto layouts, you can achieve it by connect it's width constraints as IBOutlet and change the values programatically.
Best way to do that is to use UISTACKVIEW.Place a stackview and add 3 buttons.You can give proper layout constraints to the stack view as you need
click on stack view-- select attribute inspector
change distribution--fill equally
spacing--0
Then after that if you hide any button,other buttons will be automatically adjusted in width
Other Possible sol to this problem is Adding or removing constraints during runtime is a heavyweight operation that can affect performance. However, there is a simpler alternative.
For the view you wish to hide, set up a width constraint. Constrain the other views with a leading horizontal gap to that view.
To hide, update the .constant of the width constraint to 0.f. The other views will automatically move left to assume position. and for equal width pervoid multiplier to width..
You have a few options:
UIStackView which was made exactly for this.
UICollectionView similar to UIStackView in a certain way, but not really meant for this. However, it does the job nicely and it's easy to implement. Sometimes easier than UIStackView.
NSLayoutConstraint by using multiple constraints with different priority so that you can activate/deactivate them as needed and get the desired result. This approach is a bit more complex by it gives you the highest degree of control and flexibility over the views in your hierarchy.
The best way to achieve what you are looking for is, like others have already mentioned, to use a UIStackView.
When the isHidden property of a UIView inside a stack view is set to true, that stack view will hide the view and take care of the layout, so you will only need to set the correct constraints for your stack view.
I have a xib file that I am planning to load into a UIScrollView in my UIViewController.
Here you can download the xib file: http://s000.tinyupload.com/?file_id=13327266143771794775.
It looks like this:
The views with the number 1 are the views with a fixed height.
The views with the number 2 are the views with a variable height. Those views must be able to expand as much as they want, creating eventually a scroll.
I don't understand why it says some constraints are missing. I tried to change priorities but without success.
What do I do wrong?
Since the below views are the subclass of UIview you need to give a constant height for either any one of 2's as shown in below image. As uiview is a container
and if you want the both heights equal select both the views and make the equal width
use Remove at build time if the content will be added programmatically
You should add height constraints to comments View and write comments View. In size inspector Tick the "Remove at build time" for these two height constraints.
This is what I'm trying to do...
I have one view controller that needs to dynamically display different subviews based on the presence of some data.
Here is a simple mockup. Each colored block represents a unique subview.
Sometimes the green block needs to be at the top, sometimes the green block won't display at all, sometimes the light blue block will be something different, etc.
Each subview has interactive elements, so I've been creating and adding them like so:
Defining a new view controller
Defining its view
Calling addChildViewController and didMoveToParentViewController
Calling addSubview on myNewViewController.view
Using SnapKit to make auto layout constraints to position the view
I want to transition to UIStackView because it seems a good support system for this view because all I need to do is stack its subviews. I'm seeing many conflicting constraint errors and unexpected view frames when trying to add subviews with their own inner auto layout constraints.
Question
Am I setting myself up for failure here by embedding the views of 4-6 view controllers in the view of one view controller?
Also, how do I give the added views properties like minimum heights or content sizes without seeing many breaking constraints with UIStackView? (So they can stack, but one of them is say, 400 tall, and the other is 200 tall)
Answer
You can absolutely do this using UIContainerViews combined with UIStackViews and UIScrollViews, it's a complicated setup so here's a starter project to get you started:
https://github.com/Rnorback/ScrollingStackView
Here's what that project looks like:
You want the containers to have different sizes. In order to do that, simply add height constraints to the containers with Autolayout. If you want to change the height of the scrolling. Then you'll need to change the height constraint of the UIStackView.
Brief Explanation
When creating this setup, you have to make sure the UIStackView distribution setting stays in fill. That way you can set height constraints on UIContainerViews.
When setting up anything in a UIScrollView you have to make sure that the object is pinned to the edges of the scroll view and has a defined width and height, otherwise the scrollview will throw a constriant error. I think of it like the scrollview tries to press in on all sides of your content view and if any side gives, the scrollview won't be able to present it properly.
Hope this helps.
I'm developing an app for iOS and I'm using the Storyboard with AutoLayout ON. One of my view controllers has a set of 3 labels, and in certain circumstances i would like to make the second one disappear.
If I use the setHidden:TRUE method the label become invisible but it still obviously take space in the view.
can someone point me to the right direction?
The simplest solution is to put the views that you want to hide inside a StackView. Then to hide the element simply make it hidden:
_myElement.hidden = YES;
StackView will squash hidden elements and they will become invisible.
I think you can link the constraint with the header file of your viewController. Then modify the constraint and commit changes.
Edited:
1) Create the IBOutlet for the constraint.
2) Modify the constraint, for example: self.yourConstraint.constant = 0.0;
3) Commit the new constraint: [viewForUpdate setNeedsUpdateConstraints];
The easiest and most effective way to handle this is using Stack Views. Insert the label in a horizontal/vertical (orientation they appear on your UI) stack view and stack view will internally take care of the spacing. Additional properties like alignment, spacing can be tweaked as per requirement. Make sure you re-establish the constraints between stack view and adjacent elements because once the views are added to a stack view all if its constraints are cleared
You will need to move the other views by adjusting their frames. This can be done directly, or if using auto layout, by giving them a vertical spacing constraints to the view being hidden.
If there are many other views that depend on the hiding/showing view, create another subview that contains all of the dependent views. The dependent views can layout statically on that parent, and that parent can have it's frame adjusted (again, either directly or via auto layout).
view
|
--- view to hide
|
--- common parent (move this with auto layout or directly)
|
--- subview's with position dependent on view to hide
--- ...
This is a late answer/solution, but I have just built a category which does just that - hiding the view without blank spaces.
https://github.com/neevek/UIView-Visibility
What is the proper way to make a fluid layout in iOS, in the sense that hidden elements do not take up space anymore?
I have a table view with in each cell a customized detail-type of view with title, subtitle and a row with some extra information:
The extra information can be up to three pairs of an icon and a label with a value. The layout of all views inside the cell is done using AutoLayout with no missing or ambiguous constraints.
What I would like to achieve is that when the value is 0, the icon and the label are not displayed and the views on the right are shifted to the left.
If I just use the setHidden: method, the width of the hidden parts are not changed, so that there is just whitespace, but no views are moved. Example:
It should look like this:
The following questions are related but do not seem to fit my case:
Fluid UI layout on iPhone
AutoLayout with hidden UIViews?
I have tried to follow the approach with creating layout constraints for the four frames that need to be set to zero: the width of the heart-shaped icon, the width of the label containing the value, the whitespace in between those and the whitespace between the label and the next icon. This did not work because I could not bind the layout constraints to the outlet in the code, and besides it seems a cumbersome method for something that should be a common scenario.
EDIT: I fixed the problem with the outlets to constraints: to do this it is necessary to create a subclass for the table cell and creating outlets for the constraints there.
With "common scenario" I refer to doing something similar in web design, where setting the display style to none is simple and has the desired effect. I expect that there is something similarly simple for this in iOS.
I have been thinking of using a collection view with reusable cells, but then I need to set up a delegate and a datasource and everything, and before I would go this way I wanted to make sure that that is the way to do it.
There is no need to remove a hidden view. Connect the constraint to an outlet in the code, and when you determine a view is hidden, subtract from the constraint's constant. Then, in the cell's prepareForReuse, remember to return the constraint's constant to the correct value.
Hidden views maintain their frame, so auto layout will have no reason to adjust the view. The correct way to do this would be to remove the views from the superview. The last thing you must do is double check the constraints. Since you will be removing views, you cannot use those views for auto layout. This will require quite a bit of constraint setting on your UI.