Programatically add "Spacing to nearest neighbour" constraint - ios

Is there a way to add a "Spacing to nearest neighbour" constraint programmatically? I saw a similar question posted but I don't think it was in Swift (I'm a beginner when it comes to developing iOS apps).
I haven't tried anything yet as I'm not sure where to start, but thought it might be something along the lines of:
view.bottomAnchor.constraint(equalTo: nearestNeighbour.bottomAnchor, constant: 100).isActive = true
I want to have it such that the scrollView I have in the top half of the screen is a certain distance from the nearest button below. I can't constrain it to the specific button though because I don't have IBOutlets and would rather not add them.

I can't constrain it to the specific button though because I don't have IBOutlets and would rather not add them
Then you are totally stuck. Your requirements are self contradictory. Without a reference to the button of some kind, you cannot possibly make a constraint to it programmatically. There is no “whoever my nearest neighbor is” reference.

Related

IOS/Storyboard/Autolayout. Center horizontal group of elements

Using autolayout in Storyboard, is there a straightforward way to center a group of elements without making them part of a subview?
For example if I have one label 50 and a second element Points, is there a way to hold them together as one and then center it.
Right now, I am able to hold the space between them constant (as it needs to be) and horizontally align but I can't get the two of them together centered. My approach has been to set a leading space before the first element and a trailing space after the second element, but something is throwing it off. I know I could combine them into one label and center it, but I'm looking for a solution that I can reuse every time I have one of these all too common situations.
Thanks for any suggestions.
Image:
Storyboard.
This scenario is very common and very simple to solve: just get rid of the leading and trailing constraints and instead add horizontalCenter to the first label regarding the view. After that all you gotta do is adding horizontalCenter to the second one regarding the first and you're set! Now both of them are linked together and well centered.
If you need more help with this, just share your repo and I'll fork it.
I know your question specified that you don't want to make the two labels part of a subview, but I'm not aware of a good way to do that and thought I would at least mention that the standard / recommended way to handle this situation would be to add "3K" and "Points" to a horizontal stack view, and then horizontally center the stack view and vertically constrain it to "Explorer" above.
This would ultimately require the same or less constraints as what you have now because you wouldn't need to create constraints for the labels inside the stack view.
See Apple references here:
https://developer.apple.com/videos/play/wwdc2015/218/?time=134
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html

What is the proper way of animate views when constraints applied?

I have to animate a couple of UIViews which I have added in a UIViewController inside the UIStoryboard. I have attached them with proper constraints so that they will always visible in a way I am looking. This is fine.
I am using https://github.com/satoshin21/Anima library to animate those views as per my need.
But the problem is they don't work as expected means, they are not animating in a direction or position it should be. I believe this is because of the constraints I have applied.
What is the best way to achieve this even if the constraints applied?
Setting, myView.translatesAutoresizingMaskIntoConstraints = true is coming up with lots of warning messages in console.
P.S. I am aware of taking references to the constraints in form of NSLayoutConstraints but this is not I am looking at as the above library is simply providing good chaining functions though we can do it without having references to the constraints.
The problem here, is that NSLayoutConstraint toggling works like properties in the sense that they are nothing but values which can be switched on/off, and alternated by playing with this toggling and other references to other possible values they can have. There's no real way of going around this that I know of unfortunately, and in fact i myself have built a small library similar to Anima, and it works rather well if you respect the NSLayoutConstraints' nature.
The proof of this is that under the hood of this Anima library, it's simply storing the animation points declared inside of the chain (inside Enum values in fact), and applying them as the animation moves along. Regardless, you should never re-set translatesAutoResizingMaskIntoConstraints to true when working with NSLayoutConstraints.
The second reason for this is that Constraints are the basis for all iOS frame operations, including .frame, and animations (which is why Anima works so well from the looks of it).
I wrote a post on this recently, but as I explain by referencing Apple:
Your problem is that when translatesAutoresizingMaskIntoConstraints is
called, methods like .frame or .frame.size are ignored/overriden
(depending on when you use them, before or after
translatesAutoresizingMaskIntoConstraints). As described by Apple:
Note that the autoresizing mask constraints fully specify the view’s
size and position; therefore, you cannot add additional constraints to
modify this size or position without introducing conflicts. If you
want to use Auto Layout to dynamically calculate the size and position
of your view, you must set this property to false, and then provide a
non ambiguous, nonconflicting set of constraints for the view.
UPDATED
Otherwise, try not to set translatesAutoResizingMaskIntoConstraints to true with these views, by doing that you basically tell your controller to ignore your constraints, and to try to apply constraints based on the .frame or .frame.size or position values set on the UIView. Thus, making your custom constraints obsolete. If by stopping this, you still get the issue, it's probably a constraint value issue, of which i can't give you much more advice without any code unfortunately.
First, you shouldn't set translatesAutoresizingMaskIntoConstraints to true if you have set suitable constraints on a view already. Setting this property to true will add more constraints to the view which leads to conflicts.
The general code for animation with constraints is
aConstraint.constant = 1234
anotherConstraint.isActive = false
thirdConstraint.isActive = true // thirdConstraint replaces anotherConstraint
UIView.animatewithDuration: 0.25) {
self.view.layoutIfNeeded()
}
Hope this helps. ;)
My solution is to remove constraints for that UIViewController and set the frame programmatically as per my needs. This works fine and no need to do this patchy thing with the usage of AutoLayout.

Button filling up stack view

I'm following the dev tutorial from Apple on iOS, and got to the part where you have to implement a custom control using a stack view. However, when I get to the part where it should show me a little red square referring to the button I added to the stack view, I get the whole stack view in red (the button fills the entire stack view).
My attributes are the following:
What am I doing wrong, despite following the tutorial to the letter? Thank you in advance.
Edit:
I use these constraints:
button.translatesAutoresizingMaskIntoConstraints = false
button.heightAnchor.constraint(equalToConstant: 24.0).isActive = true
button.widthAnchor.constraint(equalToConstant: 14.0).isActive = true
This is the expected behavior of a stack view with one arranged subview. If you have placed constraints on the stack view that make it larger than its arranged subviews those subviews will expand to fill the size of the stack view. Or if the stack view has no constraints on it, it will conform to the size dictated by its arranged subviews. Either way with one arranged subview that subview will take up the entirety of the stack view.
In the tutorial, there are no constraints on the stack view so it shrinks to the size of the constraints set on the button, as it is the only arranged subview in the UIStackView. You should open the size inspector stack view to ensure there are no constraints set on it. For more about stack views and layouts you should see here.
Alright folks I got it. I had the horizontal stack in the wrong place in the view. I had the same issue and I used the alignment -> top but that only fixed my horizontal not my width. The true issue was that I placed the Horizontal Stack View in the wrong location. It says "and drag one into your storyboard scene so that it’s in the stack view below the image view" when I placed it as shown it sized correctly. correct location for horizontal stack
I realise that an answer has been accepted for this question, however, I came across the same problem when following the tutorial. Whether or not this is the expected behaviour, following the tutorial exactly results in different looking interfaces on running the app in the simulator.
Something is not quite right with the constraints and so the constraints set in setupButtons() were not being implemented.
button.heightAnchor.constraint(equalToConstant: 20.0).isActive = true
button.widthAnchor.constraint(equalToConstant: 20.0).isActive = true
To solve this I had to change the stack view allignment attribute from fill to top as shown below:
This fixes the interface so that it's the same as the tutorial screenshots. Hopefully this helps anyone else coming across this issue in the future.
In recent versions of Xcode (v 9.0.1 as or writing) it will complain in the debugger output. It mentions that you may have an unwanted constraint. If you remove the constraints from the storyboard, the code should work as intended.
I follow the tutorial too and I had the same Problem.
I solved it, by deactivating the red contrains in the marked screenshoot.
I uploaded another screenshoot, to show you my other settings.
I am Beginner and it was totaly luck and I want to share this luck^^
other settings
marked screenshoot
enter image description here

What if I use "Add missing constraints" option from storyboard, for assigning constraints in storyboard?

My question is that, can I trust on
Resolve autolayout issues’ - “Add missing constraints”
option(as in the attached Screen shot), which automatically adds constraints to the objects present in the storyboard?
I used this and tried running the app in all screen formats and it works fine, so can I continue using this or is it wrong to consider “Add missing constraints” for the constraint design. I’m new to auto layout and any kind of response, explaining this concept will be appreciated. Thanks
Utilizing the automatic constraint system is a bad idea. Most of the time, it won't work dynamically for all screen sizes. It generally adds constraints so objects appear correct in the current resolution you're designing in.
For example, it may pin a label you have placed in the center of an iPhone screen based on the distance from the left edge of the screen instead of the X value. That distance from the edge is going to stay the same when you run it on an iPad and it's going to be significantly off-center to satisfy that constraint.
However, depending on the situation, it could pin them correctly (IE leading edges to the super view instead of a constant). You can use the automatic constraint system for suggestions to reference what you need to add still, but I would not rely on it for dynamic UI.
Spend your time learning autolayout instead of throwing darts in the dark, it's really not as intimidating as it seems!
No you should not trust. Add missing constraints will add constraints that are missing. It will not add constraints that's your design actually want.
So I suggest you to understand what constraint you'll require to complete UI.
`For every control, Compiler need to know its : x,y,width and height.
For example : You drag & drop UILabel on your xib. Now you add top space constraint. So compiler will give warning. Need constraint for : X position.
On above example width and height will take according to text of label. Now you had given top space so its y position is known.
But for X you didn't give any constraint. In this case if you use Add missing constraints. compiler will add constraint for x position according to your placement. It may be your require constraint or may be not.
No iT just add the required constant so may be they are fixed so remove all constraints and try again.
Just like what the others say, "Add Missing Contraints" will always give the result of the layout that you desired. It's best that you learn to add constraints manually. But, there are times that you can be lazy for a couple of seconds by using that method but only for very simple layout.
I'll just share my thoughts about when should we use this method.
I use "Add Missing Constraints" when:
My layout is very much simple, it's like I know that when I do it automatically will yield the same result as doing it manually. This help saves a lot of time.
I am setting up constraints manually, but sometimes I don't know what constraints I am missing because the object that I am setting the constraints still shows red lines(missing constraints). This is just my purpose of learning.

Swift: centering a label with another control in the way

I'm wondering if I can move a label to the center of a view even if there are other hidden controls in the way. I'm using Swift 1.2 and I'm using auto-layout for the initial position.
So I really have two questions:
How can I move a label to the center? I've found plenty of examples of moving to a particular location based on the original position. I just want the center. I tried this:
self.labelTest.center = self.view.center
Will it work 'over' hidden controls or do I have to move them too? i.e., to get them out of the way
Thanks
self.labelTest.center = self.view.center
This instruction won't be affected by the existence of any other views on your self.view if autolayout is off. However if autolayout is enabled depending on what constraints you've set they may interfere with the positioning of your views. So either turn off AutoLayout or ensure the constraints don't hinder your view being centered.

Resources