Swift UIView widget autolayout not working - uiview

I have a UIView "widget" (created via a separate XIB file and corresponding Swift sub-class of UIView) that is inserted into the main storyboard so that it can be easily reusable. However, the autolayout constraints added to the widget (XIB) isn't working.
This is how the widget looks like:
The idea is that the 3 metrics (UILabels) are distributed evenly through the widget. Some of the key constraints include:
Vertical align the 2nd and 3rd metrics with first metric
Ensure 2nd metric is horizontally centered in superview
Ensure 1st metric is a specific distance from left edge
Ensure 3rd metric is a specific distance from right edge
And so on...
However, when I run the app, it looks like such constraints aren't imposed after the widget is inserted into the main storyboard. The 3rd metric never shows up, and the 2nd metric isn't centered horizontally. Just to confirm, I added red border around the UIView, so that I can see the entire widget. The entire widget shows up in the superview, just the metrics aren't aligned properly as intended.
Any idea why this is happening? One alternative I'm considering is just putting the metrics directly on the main storyboard view, but I'd rather not do this so that I can reuse the view/code...
Update:
As #Peyman asked, here is a clearer version of the constraints. I've changed the labels to left/center/right to make it easier to correlate the constraints with the actual UI element in the XIB:

I finally found the reason -- it looks like the self.view of the widget isn't filling the entire bounds of the widget, for some reason (I don't really understand the view hierarchy so I'm sure someone else can explain this better). But the solution is basically one line of additional code in the init function of the UIView:
self.view.frame = self.bounds;

Related

Wrapper does not take it's Intrinsic Content Size as sum of it's children and constraints between them

I am creating popup that measures it's size (here only height) from the its content.
Popup consists of two half (top and bottom). I have decided to wrap top half into separate wrapper view for clean code, so I have added UILabels, UIImages etc. into it in the separate method, but now I am facing problem with it.
Their size for AutoLayout is 0! So, I have a size of popup less than needed:
But if I remove wrapper then everything is OK:
I feel that it is enough data for iOS to render it correctly, but I don't know the command to force iOS to calculate size of wrapper basing on sizes of its subviews and constraints.
I have tried invalidateIntrinsicContentSize on the wrapper, but didn't help.
I am marking up from the code, so I don't forget to set Translates autoresizing masks into constraints to false for child views.
Ok, It is figured out that I forgot to joint top and bottom of wrapper with top of top view and bottom of bottom view respectively.

MarqueeLabel text won't scroll

I want to display a label that continuously scrolls horizontally if it doesn't fit its superview. Kind of like on television when you have info showing up at the bottom with scrolling text.
I use MarqueeLabel/Swift pod
I created a sample project with a simple label that doesn't fit its superview:
I set its class as a MarqueeLabel:
I added some settings just as shown in their demo project:
And finally added this in code, same thing, I copied/pasted it from their demo (sorry for the image this time I couldn't get the formatting to work on stack-overflow!):
Any suggestion ? My only doubt is that when I set the class to be a MarqueeLabel, it automatically sets the Module as "MarqueeLabel" whereas I would have expected it to name it after my project name : "TestMarquee"
The problem maybe is the fact that your label view is out of the visual bounds of the parent view, thus you might need to add constraints to it.
I suggest you limit the label with 10-10 constraints on the left and right side respectively, and center it horizontally and vertically.
This way, the parent view controller will be able to layout it properly for you.

Auto Layout: Displaying content relative to container

I'm having some issues developing an iPhone application. I have a UITableView on a screen and have made a template for how I want to lay things out. I made sure that the constraints are satisfied and when my program compiles, I get no auto layout issues. However, when I run my program on the simulator, some of the text is not shown but I know it should be there. Here is how things look on the Storyboard:
However, this is how things look when I run the program on the iPhone simulator, it appears as so:
I am only worried about the From Date and To Date fields not being displayed because if I move them more to the left, I can eventually see them. Moreover, I made sure to make the To Date field's Trailing Space to Container Marginby 8 px so I don't really understand why these two fields aren't showing. Any help would be appreciated. Thanks!
Edit: Image of To Date constraints:
Edit 2: Image of how table view cell looks like now:
Most likely the labels are not showing because of size classes and the difference between the different screen sizes. In your story board the original view controller is a square shape. Make sure to pin the labels to the side of the cell that you want them to attach to. This will make sure they stay where you want them to. Also make sure that you pin the actual table view to the superview so you can see the labels. I have always pinned to the top, bottom, and both sides, to accommodate different screen sizes and rotation. You may need to change the constraints for the other size classes. This may make some things look they are bunched up a bit with the smaller screen size, but you can always change the font or the format of the cell to fit everything in.
If you want to change a constraint for another size class, just select that size class at the bottom of the story board. Select the label, and then in the size inspector you can make the constraints you don't want to be unable, and hook up some other constraints to make it work. Ray Wenderlich's web site has a great tutorial on size classes and adaptive layout. You can find it here.
Happy coding!!
Your "missing" labels are probably too far to the right, outside the screen boundaries. This could happen if your view controller is wider in the storyboard than when you run it. Make sure that your labels have constraints for trailing space -- that will cause them to always be within the screen bounds no matter the screen width.
Also, use the Debug View Hierarchy in Xcode to see where those labels actually end up.
UPDATE:
Try overriding awakeFromNib method in your UITableViewCell subclass:
override func awakeFromNib()
{
contentView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
}

Fill UIScrollView with its content using autolayout in iOS

I am making a form based UIScrollView, which will contain some labels and text fields.
My ScrollView Height will increase as per the iOS device height.
PS: I do not want to add constraint to each and every element of the Scrollview, because in my case there could be 100 form fields.
What I want is, the inner content to fully occupy my scrollView like this:
Till now there a are no special constraints, the button is tagged with the bottom edge and the scroll view is pinned from the top edge. Also, the vertical spacing between scrollview and button is defined.
This is the autolayout constraint screenshot.
If the number of labels is variable, I recommend doing them in code, rather than in Interface Builder.
In code, you can use a loop to set every label to have the same width/height as the one above it. You may want to set their height to be >= a minimum value. Be sure to anchor the first label with the top, and the last label with the bottom.
But this can be cumbersome, why not just use a UITableView? you may modify the row height to let the cell fully occupy the view.
- tableView:heightForRowAtIndexPath:
- tableView:estimatedHeightForRowAtIndexPath:
I just face the same issue and already write a pod called TLFormView that do exactly that: a form based on UIScrollView.
It also has some nice features like:
declarative form taxonomy with TLFormModel Just extend it, add the properties you want and that's it. No delegate, no event handling, no boilerplate.
a nice way to handle different layouts for iPhone and iPad
conditional visibility with an NSPredicate that can access all the values in the other fields (e.g: show field A when field B has certain value)
in place help with a popover
all the fields are TLFormFields that extend UIView so you can place whatever you need.
You can try it right from the command line with pod try TLFormView.
If you want to know more I wrote some blog post about it here.
Please let me know your thoughts about it here or as a comment in the blog posts. Also any contribution is extremely welcome in the GitHub repo

How do I successfully use AutoLayout and Constraints in Xcode?

This is going to be difficult without the rep needed to post images... however...
I currently have a storyboard layout in Xcode.
I have a UIViewController which is split in two sections, the upper UIView, and the lower UITableView (For now, we can ignore this, however the same issue applies to the table view, and advice is also appreciated)
In the UIView, I have a ProgressView, which spans the entire width of the UIView, and is snapped to the padding distance from the edge of the view. The ProgressView is set to 50% and falls in the middle of the layout in the storyboard designer.
When this is simulated, the progress bar appears to be sitting well above 90%. Issue is, when the progress bar is shrunk (or the width changed in the storyboard layout editor) to about half the 'visible layout', the progress bar takes up 'most' of the simulated screen, and correctly displays the 50% progress.
I'm assuming this has something to do with the AutoLayout or Size Classes. I'd like to learn the use of this autolayout and constraints properly - as such, disabling either of these will not be acceptable. The suggested constraints are not returning my expected results.
Edit: I've figured out something that seems to work satisfactorily, see the given answer. But still keen to see some actual layout advice.
Edit: Applying the same principle to the UITableView in the lower half of the UIViewController and it also fixes the problems with Separator Insets.
I have found one solution.
In storyboard editor, open the document outline.
Hold rightclick and select the ProgressView and drag to the Parent UIView, release and select:
Leading Space to Container
Trailing Space to Container
Center Horizontally in Container
(Finishing here still has issues because the UIView exceeds the width of its parent still.... so do the same to the UIView)
In the document outline, hold right click on the UIView and drag to the Parent View, release and select:
- Leading Space to Container
- Trailing Space to Container
Now, I have a perfectly centered ProgressView with it sitting between the two edges and with the 'padding' on either end. Exactly what was required.
This issue seems to have spanned from utilising nested UIViews.

Resources