I am new in auto layout feature for iOS. I found very good tutorial for this here
Now I am practicing by myself and I create one simple registration form using autolayout like this:
view->scrollview->all controls
As you can see parent for all control is scroll view now I am maintaining trailing space to superview(here Scrollview) of textview to 20 and I also remove the fix length for all the text view so in landscape mode textview width will increase automatically by maintaining the trailing space but the result is like below image (landscape view):
As you can see the trailing space is not maintain. If I set all the control directly in view and remove scroll view than it is working perfectly well. Am I missing something?
Trailing and Leading space of "Registration" label is causing issue in your case.
So in order to get rid of this situation follow these steps.
Give Center Alignment to Registration Label from xib.
Give full width to Registration Label. This will cause Trailing and Leading space to match with superview.
Run your app and check layouts. :)
Related
I'm trying to apply a full height to the following splash screen
But it doesn't work even by setting all the imagens constraints to 0
Maybe is something related with the safe area
Here is the graphical representation what you need to do. You need to add constraint from superview not from safe area
You need to ignore the safe area insets. Besides the constraint value that you're setting in the image, there is down arrow from the menu you getting by pressing the down arrow select super view and you'll get the result you need.
Note: Do this for both top and bottom to make it full screen. Also, don't forget to remove the existing constraints if you've already created them.
I need to create a UI where, as the user types, the cursor/typing area stays in the middle of the page and the newly typed text is pushed 'up and off' the top of the page.
I've tried to set the cursor position to the bottom of a text view which covers 0.6 of the superview but that doesn't work (presumably because it doesn't have any text?). This is a great answer for general cursor placement but my use case isn't catered for.
The code I used to try place the cursor at the end of the text view is :
func setCursorPosition() {
let newPosition = textViewOutlet.endOfDocument
textViewOutlet.selectedTextRange = textViewOutlet.textRange(from: newPosition, to: newPosition)
}
This doesn't work because it is looking for filled in text but sometimes the text view would be empty and I'd still need to load it on the bottom line.
The effect I'm trying to create would look like this :
quite a complex problem I think - any ideas?
For people who have this problem in future. I solved this by coming at it from a different angle. Rather than attempting to place the cursor half way down the page, I removed the height constraints and made the text view dynamically resize based on the content.
Then I adjusted the constraints (helped by this answer) to fix the space to the bottom safe area but didn't specify a height.
This way, the text view dynamically resizes but in an upwards direction. When it reaches the gradient I have placed over the frame it starts to fade out.
Perfect (I also disabled scrolling to make this work)
Top tip - if something seems really hard there might be a different way to approach the problem!
I've tried to get this to work but interface builder is doing my head in and I was wondering if anyone has a proper solution for this.
So I want to have a stackview that contains a label with multiple lines inside. The first hit on google (read here) tells you to embed the label within a view (A), then drag that view into another view (B) (because the embedded view (A) has a 20pixel pad) and then unembed the first view (A).... voila. Except this only tricks the stackview for horizontal stacks and if you continue to stack the view you will still have a ton of problems (I will demonstrate with screenshots later in the question).
I found another guide on google that criticizes a potential fix for the problem, fixing the stackviews width. The author makes the point that Apple didn't intend for you to be doing that, after all it's supposed to be auto layout, not fixed layout. This guide theorises that the issue is just a bug and that you can create a stackview with a single line label, set it all up and THEN add the multiple lines. I tried this and it didn't work, it simply messed the entire stack view up! The stack view will warp and essentially break unless the label has number of lines set to 1 and only 1. (Image 1) Stackview with label set to have multiple lines.
So I talked earlier about embedding the paragraph label within a view. This doesn't cause any errors in the storyboard,(Image 2) you can't really align the text properly with the other UIStacks but that's not an immediate problem for me to solve. What IS a problem is what happens at runtime....
Simulator, Portrait (Image 3), Simulator, Landscape (Image 4).
I tried running this on an actual device to see if it was just a simulator bug but the same thing happened on my iphone 6. Safe to say this is probably not going to work!
Oh and just before we go any further, I am building the stack views in the following way:
[name - placeholder]
[phone - placeholder]
[address - placeholder]
, setting a spacing of 8 and equal fill
,vertically stacking all of these stacks (3 into 1) and setting a spacing of 8
, vertically stacking the details titles with the big stack and 8 spacing
,finally adding the title and button into the stack view with a spacing of 32.
I then apply some storyboard constraints: in this case just centre vertically & horizontally, so the view is always centred and displays properly in both screen orientations.
Even though this isn't aligned properly, this is the view before applying the stacks and constraints, this is what I want my endgame to look like: Looks kind of silly, but I want to figure this out so I can actually stack my paragraphs! (Image - 5).
So now hopefully I've established that you can't really embed the label within a view as it doesn't render correctly at runtime, and you can't trick the stack into adding new lines.
How do I put a label with multiple lines into a stack view safely?
This is almost an offshoot question but when you try applying a stack to a paragraphed label, it sets the width of the label to be absolutely massive (sometimes it throws an error that interface builder can't render it Demonstrated here (Image 6). I've seen this happen a few times and don't really understand how xcode thinks that is a sensible option.
I don't want to apply fixed widths to my labels or stacks because I'll only be left with another warning, and warnings are bad!
I'm pretty lost at what to do, if anyone knows of a way this can be achieved I would be eternally grateful!
Thanks
This really seems to be a bug.
A workaround that works for me is embedding the multiline label in a view and leaving it there.
That fixes the layout on the Storyboard editor and also works in the simulator.
A weird thing is that if I have several multiline labels on the same StackView I only have to embed one of them in a UIView, and then all the other multiline labels will behave properly.
While I do agree this is an issue in UIStackView as layouting should work according to the intrinsic size of the UILabel.
When using stackview with multiline label, it is not able to update its size according to the label.
For resolving this issue, use preferredMaxLayoutWidth property of the label and set it to any value.
label.preferredMaxLayoutWidth = 1
Note: This even worked for me when I set it to 1
The preferredMaxLayoutWidth property as defined in the Apple Docs:
This property affects the size of the label when layout constraints are applied to it. During layout, if the text extends beyond the width specified by this property, the additional text flows to one or more new lines, increasing the height of the label.
which we do want to increase for a vertical UIStackView.
the solution is about embedding the UILabel inside "view without inset".
and then update your constraints.
I am trying to use the auto size classes from the storyboard on xcode 7 to position UI elements in a controller. The problem that I'm running into is that when I try to use the "Add missing constraints" function (located at the bottom right corner of the console), it positions my UI elements correctly except for the last elements (pictures describe better). The first image below shows the storyboard file where I just want 3 buttons (stacked above eachother) to be the same width and length to be on the top right corner of any screen.
However, when I add constraints and run the simulations, it seems like the top two buttons are positioned correctly with the correct length and width but the third button is out of place (image below).
So my question is, am I forgetting a step to make all buttons position themselves? Or should I try to convert everything to a percentage and place UI elements based on the percentage of the screen (if so, how would I go about doing that)?
I've also tried adding another blank button (removing the button label) underneath the 3rd button and adding constraints like that but it didn't work for me. Let me know if you have any suggestions, thanks!
In you case, Autolayout the constraints you need to give to UIButton is 4 constrains.
Leading
Trailing
Width
Height
If you miss any of them, then surely you will get an error. So, what's your error is?
To the third UIButton, you have not given the height, while to the above two buttons you have given.
So, just remove the bottom constraint of UIButton and give the equal height to above UIButton.
FYI, never use Add Missing Constraints without any confirmation from your side.
Update:
Check this video to remove trailing or leading margin:
http://sendvid.com/1h8deg18
You can actually see the solution in action if you use the Preview screen while setting up your auto layout constraints. I just created a similar view and buttons and stepped through the process. I coloured the buttons and named them to make things obvious.
I added the three buttons. At this point, none of the buttons show up in the preview.
I then setup the auto layout constraints for Button1. If you want the buttons anchored to the top right, then you don't need to worry about the leading constraint. You need width, height, top, and trailing.
Now Button1 will snap to it's position in the top right corner of the preview screen.
Now do the same thing for Button2. Set width, height, top (vertical space to Button1), and trailing.
Button2 will now snap into place in the preview.
Now the same thing again for Button3. You anchored the first button to the top right of the screen. Then Button2 to the bottom of Button1 and the right edge of the screen. Then again for Button3. You could also align the edges of the 2nd and 3rd buttons, if you prefer that to trailing space.
Now you'll see in the preview that your buttons are correctly positioned, regardless of device.
As long as you specify height and width for each button, you don't need to worry about the left edge or the bottom edge of the screen at all. They each know to "stick" to the top right and they know what size to be.
** Note: If you're not familiar with the "Preview" option...
With your storyboard open, hold Option and select storyboard again to get another copy of the storyboard on the right side. Highlight the view controller you are interested in on the left side. On the right side, select the Preview option as shown below.
Now you have your storyboard and the preview side by side, so you can see the exact impact of any auto layout changes you make. You can also add or remove devices to the preview.
I am new to ios development and still trying to get hang of autolayout. The problem that I am facing can be better explained with images below
Now I am removing the "Login with a social network" on iphone 4. What I want is how to center the google plus icon between the "OR Label" and "Start without registering" button
and it should also resize to fit between them.
what kind of constraints does it need to achieve that. If someone can point me in the right direction that would be great help. I have been breaking my head over this entire day. Thanks.
to center [g+] between [or] and [start ..] buttons:
you need to do two things.. on the storyboard:
select [g+] and [or]
select editor->pin vertical spacing
and then
select [g+] and [start]
select editor->pin vertical spacing
you should see a vertical line show up between the two objects each time. This is to indicate that that space will always be the same weather on a 3.5" or a 4" iPhone display.
I don't see why you want the g+ button to resize.. that actually goes agains the UI guidelines which instruct that different users shouldn't have different user experiences (see the reason behind why there isn't a replacement for the iOS 7.0 deprecated sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: method)
The same logic that discourages changing font sizes on labels/buttons depending on form factor etc resulting in different users having different experiences, is the same logic that would discourage you from scaling up or down your [g+] button depending on form factor circumstances as well.
If you're just trying to get the "g+" graphic centered between the "OR" label and the "Start without registering" label, you can:
Add a view (that you won't really see because you'll make it transparent, but it's useful for alignment purposes) whose top constraint is linked to the "OR" label and whose bottom constraint is linked to the "Start without registering" label:
Then put the "g+" graphic inside that view, aligning its center vertical and horizontal constraints with its superview's.
If you do that, the "g+" button will stay in the middle between those two labels (assuming, of course, that the "Start without registering" label has a bottom constraint to its superview, i.e. It's pinned to the bottom of the view).
In terms of resizing that button, I'd personally advise against that, if you wanted, you could, for example, remove that transparent view we created above, and just do that trick with the "g+" image/button itself. You will want to set the content size of that imageview to be "Aspect Fit" (so it doesn't get distorted).
Again, I really don't like that latter approach, but you can do it.
I gather that you want to remove the "Log in with social network" label at runtime. There are two approaches for that:
A simple approach is to create an IBOutlet for the height constraint for that label, e.g., logInWithSocialNetworkHeightConstraint and then you can do:
self.logInWithSocialNetwork.text = nil;
self.logInWithSocialNetworkHeightConstraint.constant = nil;
[self.view layoutIfNeeded];
The alternative is to define a constraint between the "OR" label and the "g+" graphic's appropriate view. This, itself, has two possible approaches:
You could define this in IB, but define it with a priority less than 1000. Because the constraints for the "Login with ..." label will have higher priority, when that label is there, those constraints will take precedence. If you you remove the label:
[self.logInWithSocialNetwork removeFromSuperview];
[self.view layoutIfNeeded];
Then the new constraint you defined will then come into play.
You could alternatively remove the "Login with ..." label and then programmatically add a new constraint between the "OR" button and the "g+" graphic's view.