How to auto Layout Labels - swift

I want to layout my labels like this using auto layout. It works fine in iPad 10.5. But when I move to any other versions of iPad with a larger screen, this design brokes. Anyone, please help me to solve this problem.

Swift 4
Use stack view
Step 1. insert labels inside of stack view
like that
Step 2. add constraints on stack view
from top, bottom, left and right alignment according to your requirement
like that ->
Step 3.
Use Stackview properties
a.) set axis of Stack view Horizontally as well as vertically.
b.) set alignment according to requirements.
c.) set Distribution according to requirements (here i used fill equally).
b.) set Spacing between labels .
See here ->
Now run. it will work, it will show same in all Device like iPhone and iPad and also (horizontal and vertical).
it will show like this(iPhone6splus)
Thank you

It seems like you create/checked constrations only for iPad or iPhone. Change a type of device scoping on Storyboard editor and you can find errors. Take care about UI for all of device types.

You can add constraints by "Add missing Constraints".
1.select your labels
2.And click the "Add missing Constraints"

Related

What should I look out for when combining Autolayout and positioning in iOS?

I am working on an iOS project that uses auto layout to set up a view with a scroll view and a stack as the scroll view's content.
All works well, and I can add UIViews until the cows come home to the stack and it does what is expected.
However the question now arises when I am about to implement the user-definable layouts for the reporting view.
The stack holds a view dedicated to user defined layouts.
The user will define the data output (for example "benefits") and the origin (top left corner) and that view will be placed there. They can place as many or as few views and pieces of data that are made available to them in this manner. They will have no understanding of auto layout and hence will solely rely on the exact positioning of these views via the top left corner and their size.
Is there anything I should be aware of before starting this phase of the project? My concern is the mixing/matching of auto layout in the global layout and exact positioning inside this one specific view.
Looking for input on caveats, code that I MUST include (for example any flags that should be set) and so forth.
Thanks for any sort of help,
D
Thanks for all the suggestions.
My concept was a little to involved for the suggestions given, however I did develop a solution that allowed the user to position the widgets by origin (top left corner) while still using AutoLayout.
For those interested, I created a "dummy" UIView to hold all of the user positioned widgets and then created Autolayout constraints based on the top and left anchors of this view.
Since the widgets are created by reading the layout from a Dictionary, if they make changes to the layout, I simply remove/refresh the layout if they make a change.
Thanks once again for the nuggets, without which I would not have thought of this solution.
D

NSOutlineView disclosure triangle vertically off center

I'm working with an NSOutlineView on a macOS app and it provides disclosure triangles for items that can be expanded.
I'm also creating custom NSTableCellView items rather than using basic cell items. This allows me to create the cell how I want visually.
My issue is that when they're displayed, the disclosure triangle on the left is not centered vertically.
Notice how the disclosure triangles are not aligned properly. They're a bit lower than they should be. If you scroll away and come back, sometimes, they automatically align themselves correctly. Has anyone been able to fix this issue before?
For what it's worth, I'm using the following code as well for the cells.
self.outlineView.rowHeight = CGFloat(integerLiteral: 66)
self.outlineView.usesAutomaticRowHeights = true
It's hard to figure out what the problem is without seeing how you've set up your project, but I'm going to give it shot.
First, when usesAutomaticRowHeights is set to true, the outline view uses Auto Layout to position the cell views. Thus, you need to be utilizing constraints in your Storyboard or Nib file, or things will behave strangely (see: your picture). If I had to guess, the prototype cell view you set up in Interface Builder is having its autoresizingMask translated into Auto Layout constraints (which, generally, causes a boatload of problems).
What I would do is this:
Open up the Storyboard or Nib document containing the outline view.
Locate the prototype NSTableCellView instance that contains the street name text field in the Document Outline to the left of the canvas. (If you don't see the Document Outline, you can open it by clicking the item at Editor » Show Document Outline in the main menu).
Next, see if you have any constraints in place. If you do, remove them by selecting Editor » Resolve Auto Layout Issues » Clear Constraints under the menu item "section" that's titled All Views in ${YOUR_SCENE}.
Now, depending on what you're going for, there are different ways to go about setting up constraints, but here's what I would suggest. Assuming you want the street name to be centered vertically with the disclosure triangle, I would add a vertical constraint between the text field and its parent cell view like so:
With the text field selected in the Document Outline, click the Align icon in the lower right-hand corner of Interface Builder's main canvas area (see image).
In the popover that appears, check the checkbox next to Vertically in Container.
In the text field on the right side of the popover, enter a value of “0”.
Finally, click the “Add 1 Constraint” button.
You’ll probably see a red error (or yellow warning) sign show up, as the view has now opted into Auto Layout, but it only has a metric for its vertical position. So we now need to add some constraints to describe where the text field should be positioned on the x axis. Like before, we’ll define the constraints using the popover buttons on the lower right-hand side of the canvas:
Click the Add New Constraints button (the one to the right of the Align button).
On the diagram at the top of the popover, click the faint red lines on the left and right side of the white rectangle. This is telling Interface Builder we want to add leading and trailing constraints.
Now, enter the desired padding you want on each side of the text field. In the example image, I went with “4” points on both sides, but obviously, you can use whatever value(s) you think works best with your layout.
Finally, click the “Add 2 Constraints” button.
Any warning(s) that were present should now disappear, as we've added enough constraints to describe the position of the text field. In theory, you should now be able to build and run your project, and the text fields should be aligned with the disclosure triangles. With that said, there are plenty of other reasons a layout can get finicky, and considering usesAutomaticRowHeights is a new API in macOS High Sierra (and Steve Jobs is no longer there to beat it into Apple developers to make everything Just Work™), there could be issues that I'm unaware of.
Alternatively, you can set usesAutomaticRowHeights to false and have some object (e.g. a view controller, a NSObject subclass, etc.) conform to the NSOutlineViewDelegate protocol and implement the outlineView(_:heightOfRowByItem:) method to return any arbitrary height you want for different rows. The nice thing about sizing rows this way is that you can allow certain rows to be larger or smaller, depending on the role of the corresponding item. There are lots of tutorials on this, so I won't regurgitate a half-baked explanation here, but feel free to Google “Conforming to NSOutlineViewDelegate protocol” for more info.
Anyway, try the steps above, and see if they do anything for you, and if they don't, let me know. I can go as deep into the rabbit hole with you as you need, so just ask. Good luck!
For those like me who stumbled upon this issue many years later, here's the fix that worked for me, and requires a lot less work.
NSOutlineView has a function frameOfOutlineCell(atRow:) and the documentation states: You can override this method in a subclass to return a custom frame for the outline button cell
You can override the method in order to provide a frame that's actually in the vertical center of the row. And an important point that I learned from trial and error, is that you don't even need to provide that updated frame. Not sure if this is a bug or what, but for me, just calling super.frameOfOutlineCell(atRow: row) in the function override was enough to make the disclosure indicator appear in the correct location.
So my subclass of NSOutlineView is this:
class MyOutlineView: NSOutlineView {
override func frameOfOutlineCell(atRow row: Int) -> NSRect {
super.frameOfOutlineCell(atRow: row)
}
}
That's all. Hopefully that works for others as well!

UIStackView and Multiline Labels?

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.

Swift Storyboard Auto Size Classes

i have a problem. I had a storyboard in Xcode 6 with the inferred size of the view controller and the "Use Auto layout" option checked. Today i wanted to use the new " Use Size Classes" option. I checked the option and then in the simulator the screen was all black!
EDIT
now that i resolved this issue i have another thing here ! I use "Add missing costraints" option to have a resize for all Apple Device, the Tab bar and navigation bar are good, but then all the buttons ( they have an image ) are in different position !
How i can resolve that ? Thanks in advance.
A black view.. if not always, is a good indicative that the view is not loaded. Size Classes introduces a new concept ...You can have several views that will be installed or not into your view depending of your view configuration. More details on images below:
This is what you will be looking for:
This is what I call view rendering configuration (sure Apple has another name for it). It is located at center bottom of your storyboard view.
This is always located at the end of Attributes Inspector tab:
Make sure it is enabled for the view that suits your testing device.
I found out that the ViewController wasn't set as Initial Controller.
You should avoid as possible the use of "add missing constrains". Is an automatic tool that almost always ends up adding unnecessary constrains or breaking others.
If you want something to look really good an stable, sadly there are no shortcuts... you will eventually end having to do it all by yourself.

Xcode 5 - Storyboard - Has no constraints

Does anyone know why I get the following message:
"The selected views have no constraints. At build time explicit left, top, width, and height constraints will be generated for the view."
I'm using XCode 5 - Storyboard with AutoLayout turned on
Found the solution!
Select the ViewController then from the XCode menu:
Editor --> Resolve Auto Layout issues --> Add missing constraints in View Controller
It appears that in Xcode 5.1 when using AutoLayout, when you create a new scene it will start without any editable constraints. They are generated at runtime to reflect the scene's intended layout.
So adding constraints in interface builder is not needed only if you wish to modify the defaults. When you do that you need to familiarize yourself with the provided tools (as seen in the "Resolve auto layout Issues" menu)
In a ideal wold layout just works without thinking to constraints, even if they work behind the scenes. It seems to me a step towards that goal. This is not to start a debate if the goal can be reached, only to say that we can expect more similar interface builder / xcode changes to follow.
You have selected auto layout on your viewcontroller , so you can't set the contraints manually , uncheck the layout , it will show the constraints automatically .