I'm trying to make constraints via Snapkit in a table view cell but my problem is I need to find out which element has max y position (The lowest one).
I have an UIImageView and next to image view UILabel elements. The label text is dynamic and could be very long or very short. Below these 2 elements, I have another one that should be aligned based on the label height, either taking image view or label.
My question is how to find which element (UIIMageView, UILabel) has a bigger Y position.
To be more clear I attached a draw with simple two cases.
Set a greaterThanOrEqualTo constraint on both elements.
In "plain language":
AnotherElement.top >= ImageView.Bottom (with constant of 12, or however much space you want)
AnotherElement.top >= Label.Bottom (with constant of 12, or however much space you want)
Related
When using Auto Layout to position a label, I always get very imprecise results. In the example below, I have aligned the top and left edges of a UILabel to a parent UIView:
There is empty space on all four sides of the text, but the amount of empty space at the top and bottom is especially horrible. It is very tedious to take screenshots and figure out how many points I would need to offset the constraint's constant value to make the text line up properly. Is there any way to for the UILabel to properly reflect the rendered text in its frame?
I have a UILabel in a collection view cell that is center aligned with number of lines = 0 and line breaks = word wrap
My text is dynamic, dependent upon requested data, so some cell's don't need two lines.
Any idea why it still wont go to the second line if needed? Getting stuck on this.
While I do not know because I do not see any code, I suggest looking at the size of the label. Are you sure the label is not getting stretched / set to a size larger then the collectionviewcell?
I think this is what you're experiencing:
I made two labels, each with:
number of lines = 0
word wrap activated
just enough x and y constraints to keep them in place on the view!
I think this is what you want:
I added constraints to each label making their width less than or equal to 300
In my app for iOS 8, I have a UISegmentedControl that stretches to fit the width of the device's screen. So on an iPad it's more pixels wide than it is on an iPhone 6+, which is more pixels wide than the iPhone 6, etc.
Centered just beneath each segment of the UISegmentedControl, I have a UILabel. So there are 5 segments and 5 UILabels. Each UILabel has a fixed width (fixed by constraint). However if the display size increases they become uncentered.
How in Interface Builder can I specify a constraint that will force each UILabel to become centered beneath each segment? I would be happy if I could just get the elements to remain proportionally spaced with each other as the display size scales, but I can't figure out how to do that, either.
All I can seemingly do is to center the middle UILabel directly under the middle segment by specifying a Center X Alignment between that and the UISegmentedControl.
I specified a Horizontal Space constraint between all the UILabels, and between the outer UILabels and the edges of the view, and set all these to "greater than or equals". They all have the same priority, but strangely, they don't all scale proportionally to each other.
The resulting problem is that the amount of Horizontal Space between each of the UILabels does not scale smoothly as the width of the device's screen increases. If I align everything to be in the proper positions on the iPhone 5S width of screen, then on the iPad their alignment is all wonky, and only the middle one lines up with its segment. The rest of them are all off center.
It appears that there is no way to specify a percentage of the over-all display width as a constraint -- you can only specify things in terms of pixels. Really?!?!
Clearly I could make the width of the objects to be flexible, but because they are text labels with right-aligned text, that screws everything up.
Surely I'm missing something here... since the point of Auto Layout is to make your interface scale according to the screen size, surely there is a way to specify a constraint as a percentage of any given view or subview... surely!!! But how? I've read the documentation and I cannot, for the life of me, figure it out.
BTW I did see that in the past, people have used crude hacks like spacer views or multiple sets of constraints, but surely those are outdated answers, and I'm just overlooking something extraordinarily obvious... right?
You can do this by making the centerX constraint of your labels equal to the superview.trailing times 0.1, 0.3, 0.5, 0.7, and 0.9 with constants of 0. To make these constraints, add your 5 labels to the view. Give the left most one a vertical spacing constraint to the segmented control. Select all 5 labels and give give them a "vertical centers" alignment constraint. Now control-drag from each label to the right side of the screen, and select the "Trailing space to container margin" constraint. Edit each one of these trailing constraints to look like this (except for the multiplier that needs to be given the values I mentioned above):
You'll have to reverse the first and second item (which you do from the pull down on the first item), change the Label.trailing to Label.Center X, and uncheck the "relative to margin" box, then correct the constant and multiplier values.
This approach will only work if the segmented control stretches all the way across the screen with no padding to the edges. If you want padding to the edges, then you need to use a completely different approach. You would need to create 5 UIViews below your segmented control -- align the left edge of the left-most one to the left edge of the segmented control. Align the right edge of the right-most one to the right edge of the segmented control. Give the 5 views equal width, and 0 length horizontal spacing constraint from each to its neighbor. This will give you 5 views that mimic the segmented control in width, with each view being the same width as one of the segments (assuming all the segments are the same width -- if that's not the case, you're screwed). Then you only need to add your labels as subviews of these 5 views, and give them centerX and centerY constraints.
Suppose I have a view that contains two columns of objects. The first column contains labels, and the second column contains, say, sliders. I want the sliders all to align left with each other. I want the labels all to align left with each other. The trick is, how can I set the spacing between the labels and sliders so that the default spacing is used between the left sliders and the longest label, thus:
label 1 slider 1
label 2 slider 2
longer label 3 slider 3
very long label 4[]slider 4
label 5 slider 5
I've placed square brackets, [], where the default spacing should be. Is it possible to add this sort of constraint in the storyboard (iOS 7)? If so, how? The trick is that I don't know which label is the longest, especially with localization.
Ideally, I could specify a bounding box around the labels and align the sliders with the right side of the bounding box.
Yes, you can do this in IB. All the labels should have their left edges aligned, and one of them should have a fixed space to the left edge of their superview (all the elements should be enclosed in a UIView). Similarly, the sliders would have their right edges aligned and one of them would have a fixed space to the right edge of the box. Give one of the labels a horizontal spacing constraint to a slider -- make that a short one, say ==8 with a priority of 900 (that's the important thing). Now, give all the labels a >= constraint with whatever value you want for the minimum spacing (and leave the priority at 1000).
I have the following cell design where the numeric label shrinks and the "Overall" label is directly underneath.
I have properly set the adjustFontSizeToFitWidth and minimumFontSize properties. The font is resizing correctly. However, anchoring the numeric label to the bottom is challenging. Particularly when the font shrinks the gap between the two labels widens and does not appear vertically centered.
I have tried sizeToFit, sizeThatFits, and using the font's pointSize. All unsuccessfully.
I am aware of sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:, but don't understand why I would need it in combination with adjustFontSizeToFitWidth.
Ah, so you want to position the UILabels in the middle of the container view (both horizontally and vertically)?
I have rephrased my answer so it will make more sense to future readers.
My code is assuming that you have the 3 IBOutlets set up:
UIView *containerView; //Your nice view containing the two textfields.
UILabel *points; //The label containing the number.
UILabel *overall; //The textfield containing the text 'overall'.
You could simply set the frame of the labels after assigning the text and calling the sizeToFit.
This first line positions the UILabel points, the only change being that the y coordinate is half of containerView subtract half of the height of itself.
points.frame = CGRectMake(points.frame.origin.x, (containerView.frame.size.height / 2) - (points.frame.size.height / 2), points.frame.size.width, points.frame.size.height);
To position the overall accordingly - say there is a distance of say 6 between the number and overall labels:
int space = 6;
overall.frame = CGRectMake(overall.frame.origin.x, points.frame.origin.y + points.frame.size.height + space, overall.frame.size.width, overall.frame.size.height);
Having read your comments, I think you are after this solution. If you want both UILabels to appear in the middle; subtract (overall.frame.size.height / 2) + (space / 2) from the y value of points like so (with the code of number 2 beneath it):
int space = 6;
points.frame = CGRectMake(points.frame.origin.x, ((containerView.frame.size.height / 2) - (points.frame.size.height / 2)) - ((overall.frame.size.height / 2) + (space / 2)), points.frame.size.width, points.frame.size.height);
overall.frame = CGRectMake(overall.frame.origin.x, points.frame.origin.y + points.frame.size.height + space, overall.frame.size.width, overall.frame.size.height);
The final point will produce an output like this image. As you can see the blue line is half of the whole image, and intersects the black rectangle (which is snuggly around the two labels) at its middle point. I hope this is what you were after.
Instead of using two labels, use CATextLayer instead. You will be easily able to make one part BOLD and the other normal. plus position and adjusting size for One layer will be easy relative to placing two labels. shadow setting, line break mode, fonts you will be able to adjust everything beautifully :)