I have a stack with 2 view inside it, the yellow takes up 70% of the stack and the green the other 30%. I want to code a button that will upon click:
Expand the stack to the top of the screen, which I have done via:
myStack.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
Then make the green box take up the whole stack, so the screen will be completely green
I have done the 70:30 thing with "equal widths constraint like so: widths
How may I achieve this functionality and what is the code of resetting everything back to normal? desired output
Change the stackView distribution to be Fill Proportionally.
Set up width constraints indepedently for each view (with priority = 999, allowed to break). (0.7 of superview.width for first & 0.3 of superview.width for second).
Call firstView.isHidden = true, it will automatically stretch the secondView to cover stackView in full - Expanded state.
Call firstView.isHidden = false, it will bring you back to Initial state.
Related
I have 3 elements in stackview.
-One is email - TextField,
-Other is password - Textfield;
-the last one is UIView and it has button in it.
When I run it, the button in that view doesnt respond, while the same view out of the stackview responds normally. ALSO when i put a button in that stackview, it acts but when it is in a view in stackview it doesnt.
I am missing something but what ?
thanks
Hey the problem is undefined constraints. Here I just created a simple solution to help you out. It is not perfect but it will helpful
When you are using stack view you need to keep few things in mind. There are two types of stackView horizontal and vertical stackView and stackView has some properties like
Axis - means you wan it horizontal or vertical
Alignment - It is simple you can understand when you see, fill leading centre and training
Distribution - In my thinking it is most important part of stack view
Fill will leave three of them their natural size, and make the fourth one take up the most space. It uses Auto Layout's content hugging priority to decide which one to stretch.
Fill Equally will make each subview the same size so they fill all the space available to the stack view.
Fill Proportionally uses the intrinsic content size of each subview to resize them by an equal amount. So view 1 was designed to have twice as much height as views 2, 3 and 4, that ratio will remain when they are resized – all the subviews get proportionally bigger or smaller.
Equal Spacing does not resize the subviews, and instead resizes the spacing between the subviews to fill the space.
Equal Centering is the most complicated, but for many people also the most aesthetically pleasing. It attempts to ensure the centers of each subview are equally spaced. This might mean that the right edge of view 1 is only 10 points from the left edge of view 2, while the right edge of view 2 is 50 points from the left edge of view 3, but what matters is that the centers of view 1, 2, 3 and 4 are all identically spaced.
Spacing - spacing is used to provide the space between objects like label, button etc.
I set the spacing between items 15 and distribution fill equally so they can fill the space available to the stack view.
here is the link to project https://github.com/waytorohit/SOreadytohelp so you can better understand.
References - https://www.hackingwithswift.com/read/31/2/uistackview-by-example
No need to give constraints
first delete view and button in your stack view and re-add then
create a viewController and of this viewController and connect it
#IBAction func clickMe(_ sender: UIButton) {
print("you click me")
}
and give some color of your button for checking and click on that
hope it's work fine.
No need for the extra view. If you delete this you can add a background colour to a normal button and change the background size and text size to make it appear the same.
If this isn't working you could go into your app design tool and make a coloured box and add this as an image into your button background.
After your button is set up you can add the #IBAction like any other normal button.
Hope it works, Toby
I'm stuck with a strange bug with Auto Layout.
I have two buttons (confirm and delete) side by side, in the same view, each taking a width that's 50% of their superview, and in some situations (when test = true), I want to hide confirm button so delete button takes all the width of the screen.
Here is my autolayout:
Confirm button:
Delete button:
Proportional width is 50% (1:2) of the superview. Now here is my call, happening in viewWillAppear:
if test {
self.confirmButtonWidthConstraint.constant = 0
self.deleteButtonWidthConstraint.constant = (self.deleteButton.superview?.frame.width)!
}
However, after doing so here is the result:
And after checking the UI debugger, I can see that oddly, this delete button now has a width of... 480, with a starting x of -160. So I don't really know what's happening here. Please help!
May I suggest a different tactic?
Embed your buttons in a stack view (UIStackView) with the buttons set to fill equally.
You can then set your button to disappear with button.isHidden = true. The stack view will handle the layout for you gracefully.
You've set the width proportionally but are updating the constraints constant property. This will need lead to the result you desire as the proportional width will simply add the constant value to the multiplier result.
Instead you should set the multiplier property of your constraints. For example:
if test {
self.confirmButtonWidthConstraint.multiplier = 0.0
self.deleteButtonWidthConstraint.multiplier = 1.0
}
I am trying to do the constraints for these horizontals button. I want the ratio of size of buttons to be the same, and the icons to be of equal widths and heights of each others.
Any idea of how i can do that so these buttons resize properly according to the screen size? Thanks!
Make groups of UIView containing the icon and text. Lets call this container view
Place all the n container views inside your storyboard as you would like them to appear. Now:
To the left most container view add a leading and bottom constraint to the super view.
Now to the second container view add a leading space of 0 (or anything you want). Control + drag your second button to the first button. Hold down shift and select equal width, equal height and align bottom.
Now apply the same constraints as your second container view to all your n - 1 container view. n being the number of container view you want to add. Now to your last (nth) container view add, one extra constraint, which would be a trailing space to the superView. Now all your container view ought to have an equal width that will be determined depending on the width of the screen!
If you want to have a specific height or aspect ratio to all your container view. Just add the height or aspect ratio constraint to your first container view and all your subsequent views will get updated accordingly.
OR
If you wish for the height to be dependent on the screen size and not maintain a specific aspect ratio, then you will have to give the first container view a equal height to the whole view with a specific multiplier like 0.15.
You will also have to add appropriate constraints to the icon and label present inside each UIView
Edit: A much easier thing for you to do would be add the icon as an image to the UIButton and add the text as you would normally to the UIButton. The UIButton will appear quite similar to the screenshot you posted. And then just apply the constraints I mentioned above.
Set the width and height as ratio of the SuperView. Set if for one button and for the remaining buttons make the height and width equal to the first button for which you defined the height and width in terms of superview height and size. Use this SO Post to see how to set height and width as ratio of the superview.
Hope this helps.
It's Simple because your All buttons are in single Direction so you can use StackView.
Just simple first apply the equal hight and equal width to all your buttons
now select all the buttons and add them in the stackview
it will be in the right side bottom. (with the constraint icon)
now simple Apply add missing constraint. it will done the work by own and gives better result. (but take care here apply it from the all views in View Controller Section)
And now Bingo try this every Size will show same.
This will work same in simulator also.
The solution is very simple.
See the image below (5 buttons)
The first (blue) button is pinned to the left and bottom of the superview
Each of the other 4 buttons (red, black, green, pink) are top aligned to the first (blue) button
Each button is using a horizontal spacing to the previous button (with a constant of 0). So red button has 0 horizontal spacing to blue, black has 0 horizontal spacing to red, etc
The Last (pink) button is also pinned to the right of the superview
Finally all 4 other buttons are set to have same width to the first (blue) button
That's it!
As for you icons, all you need is to set them to have same width & height to the first icon you have
So I'm making an app for people to learn Japanese (without having to pay to learn more like the rest) so I can understand the ins and outs of Xcode & Swift 3.
The original plan was to have the initial view being two buttons that take up half of the viewport.
I set the buttons to be equal heights to the View and gave them a multiplier of .5, but when stacked on top of each other, the second button extends past the bottom of the screen (as shown below).
It all seems to nail down to the status bar being involved, so how would I account for the status bar while having the buttons be half of the screen - the status bar?
Thanks for the help (if there is any),
James.
You have the top spacing constraint for your top button set as relative to the "Top Layout Guide", which directly under the status bar in your view.
If you give that constraint a constant of -20 (the height of the status bar), it will move the buttons up. Alternatively, you can set the top constraint to be relative to the container margin instead of the top layout guide. This will ignore the status bar.
If you want to keep the spacing with the status bar, simply set the constant on each button's proportional height constraint to be -10. You can leave the proportion as .5 - the constant will be applied separately.
So what should work is:
Set up your constrains similar to this UI (equal widths and heights)
And put UIView on the top.(Height of this view should be 20).
Let me know if it helped you :) (So I can improve my answer)
I really wish I could get my head around auto layout. It seems that whenever I read an abstract description of how things are supposed to work it makes sense, but whenever I actually try and put it into practise it always causes massive headaches. So, apologies if there is already an answer out there for this but I couldn't find one.
The problem should be relatively simple. I have a container view, which contains two subviews, shown here in hideous colours for maximum readability :) :
The bottom (black) view, should remain at it's current size and maintain the spacing between it and the red view, and the spacing between itself and the bottom of yellow view.
The red view I want to be able to dynamically change its height, causing the black view to shift up/down accordingly whilst the yellow view resizes to fit both the red+black views.
For the black view, I've added constraints to:
Set the height to 94
Pin the leading and trailing space to superview
Set the top space to the red view at 51.
Set the bottom space to the yellow view at 20.
I am trying to understand what seemingly-mystical set of constraints I need to add in order that, when the red view is resized vertically, the black view stays its current distance from the red view and maintains its size, and the outer container view resizes accordingly so that it contains the red view + black view + vertical spacing between the views.
For the red view, I've added constraints to pin the top, left and right spacing to superview, but have had no luck working out the vertical constraints. Currently I've got a constraint pinning the height =114 with a priority of 999 and a constraint with height >=114 with a priority of 1000 thinking this would ensure the view is always at least 114 in height...
The fun starts when I try and manually set the height of the red view.... I've added a button on the view, and when the button is pressed, I manually set the bounds of the red view. (The red view's default height is 114):
CGRect bounds = self.redView.bounds;
bounds.size.height = 300;
self.redView.bounds = bounds;
When I run this and press the button, the view goes from this:
To this:
To me this makes no sense whatsoever. Why does this result in:
The Y origin of the red view changing? Particularly when there is a "required" constraint telling it to stay 20pts from the top of yellow view.
The spacing between the red and black views breaking down, even though the constraint on the spacing between them is "required"?
The vertical size of yellow view not changing. Again, despite the spacing between red+black, and me having tried just about every combination I can think of in terms of compression resistance and content hugging priority.....
I really want to understand this, so would be really grateful if someone can explain what additional constraints / changes to constants are required, but more importantly WHY they are required, because to me it doesn't seem clear at all how the layout system comes up with its answers....
Any clarification much appreciated.
Thanks in advance
(All code above is running on iOS 7 and built with Xcode 5.0.2).
You don't need any fancy constraints to do what you want here -- no inequalities or messing with the priorities. In addition to the constraints to the sides, the red view should have 20 to top, 51 to black view, and a height constraint of 114. The black view, has a 20 to the bottom and a height of 94. The superview (yellow) should have zero constraints to top, left and right -- no height. You should have an IBOutlet to the red view's height constraint. When you want to change its height, modify its constraint (don't set frames):
- (IBAction)resizeYellowView:(id)sender {
self.heightCon.constant = 300;
}
Everything is linked together from the top of the yellow view to the bottom with fixed values, so the only thing that can change when the height of the red view changes, is the height of the yellow view.