Show left axis label width fixed or mulitline in Charts library? - ios

I am using charts(https://github.com/danielgindi/Charts) library for design charts in my application.
I am facing issue with display label width, I am trying to set fixed width label so that I can display the chart in max space. but now title text taking too much space of the screen.
how can we avoid this problem?
here is the screenshot for reference.

Try set multiline mode for label:
label.numberOfLines = 2
label.text = "Regional Safety\nWalks"

Related

How can I set the height of a UITextView to exactly match its truncated content?

I have a UITextView whose height I would like to limit to some reasonable value, with the text truncating if necessary. How can I make sure that the height of the text view matches that of the truncated content? If, for example, I set the height to a fixed value, there will some variable space at the bottom of the text view which will affect the layout of items below it.
Is there some way to set a desired height, measure the truncated text, and then use that measurement to more precisely adjust the height? Is there even a way to measure the height of the displayed text within the UITextView?
Edit
I need to clarify:
I do not need help truncating the text. As you can see from the screenshot, the text is truncated already.
I cannot measure the text because I would need to measure the the truncated text, which I don't have access to.
The gap at the bottom of the text view is not related to the textcontainerInset.
This is how the screenshot is currently built:
The text is set to some long string.
The text view is artificially constrained to some height, let's say 300. This produces the truncation.
Because 300 is not a precise multiple of the line height, there is some additional space below the last truncated line.
What I would like to do:
After sizing the text view to 300, measure the precise height of the truncated text so that I can then resize the text view a second time to fit it without the additional spacing (e.g. set it to 285 if that is the measured size).
Or, some other method to achieve the same end result.
I expect it's truncated because of your constraints. So you need to calculate the text size in the code and update the constraint value:
let boundingRect = (textView.text as NSString).boundingRect(
with: maxSize,
options: .usesLineFragmentOrigin,
attributes: [ .font: textView.font ],
context: nil
)
heightConstraint.constant = boundingRect.height.rounded(.up)
The result of this operation is float and not related to pixels. When the view size is calculated by the constraints, it get's rounded to pixels (0.5 or 0.333...), that's why we need to round it by ourself to exclude unpredictable cases. To get pixel perfect height you can round it according to screen scale:
textViewHeightConstraint.constant = (boundingRect.height * UIScreen.main.nativeScale).rounded(.up) / UIScreen.main.nativeScale
Also, as #nghiahoang mentioned below, don't forget to zero the insets
textView.textContainerInset = .zero
Here's my sample project
Compile the solution of Philip and set the inset.bottom to 0
textView.textContainerInset.bottom = 0
Directly, it is not possible. If you want to do it, you have take UILabel behind the UITextView. Because UILabel has the property to auto extend the height and width based on text. Now. set equal constraints of UILabel to UItextview.
what should be constraints, let me explore step by step :
set leading and trailing of UILabel.
Fix top constraints of uILabel.
you not need to set height constraint but if you want, you can set greater than equal to constraint of constant 20 or 30.
Now set leading, trailing,top and height constraints of UITextview equal to UILabel.
Now whatever you set text in UIlabel , give it to label as well. I did not in past. If you will find any issue please ask in comment

Advance usage of UIStackViews

I want to achieve this using UIStackView
I know this is possible using the conditional code/conditional constraints in the .swift file by activating and deactivating some constraints.
How can I achieve this using UIStackViews?
Below are the results I want to achieve.
1) Space must be constant between small gray dots i.e. spacing value 12
2) Size of the small dot is fixed i.e. width=5 for small dots and also fixed for the circle with text.
3) I want to show #n(e.g. 6) dots for the iPhone6 between two big circles. Dots must be more or less based on the screen size.
Something like this:
StackView with 5 views : alignment = fill, distribution = fill
Views 1,3,5 (gray views) - view with custom width for the circle with text
Views 2 and 4 - equal width
Views 2 - stackview with 6 views for dots : alignment = fill, distribution = equal spacing
Please let me know IF any additional information is required.

Vertical alignment of iAP currency labels

I'm having some issues with the vertical alignment of different currencies for some in app purchases. My purchase labels all align perfectly in dollar figures, but for larger Japanese Yen figures they appear to be pushed up. The only difference appears to be the comma, but I'm unsure how to resolve this.
I'm aligning all my labels using
coinLabel.verticalAlignmentMode = .center
Thank you in advance!
US Example:
Yen Example:
You need to use .baseline, not .center as the , descends below the baseline. Using .center centers the entire text frame around the origin. Using .baseline places the baseline of the text at the origin and ensures that the descender does not impact the placement of the text in the node.

Fonts not fitting properly in UILabel - Ascender or Descender cropped

I've done extensive searching/reading/testing and cannot find a solution to this problem.
I've tried since iOS 4.3 and it's still not resolved in iOS7.
The problem is this: Fonts at large sizes can have their Ascenders or Descenders cropped in a UILabel.
Here's a screenshot directly from the Xcode 5.1 UI (no code at all!) showing the problem - font size 300 points:
As you can see, even a simple font like Helvetica Neue (bold or not) has it's Descender cropped. (You're seeing UIViewController > UIView > UILabel)
If you try this and then change the point size you'll see the font scale down, and eventually the Descender will not be cropped. Here it is again at 160 points:
Notice also that some fonts do not get cropped and others do - try Noteworthy, or Papyrus, or Savoye LET - all of which are standard iOS & fonts....
I'm talking about Height here - I know I can use adjustsFontSizeToFitWidth=YES to see the entire length, and I also know I can use sizeToFit, however neither guarantees no cropping of the Ascender/Descender.
Notice also that calculating the height using Ascender/Descender values does not help as the main issue is that the font is not centered vertically within the label when it is drawn. (If it were, it would be a simple calculation.)
So here is the question: How can I show a font as tall as possible and be assured that the Ascender/Descender is not cropped regardless of the font used?
EDIT:
I re-read my question and realized I did not ask it properly - I'm able to resize the label to fit the font - that's not the problem. Here's the revised question:
How can I draw text in a UILabel as large as possible and be assured that it is centered vertically, with no cropping of the Ascender or Descender?
I can easily figure out the overall height of the text, and once I know it will fit, how can draw it in the UILabel vertically centered?
For Example: In the first screenshot, the text "Tg" is cropped, but it is easily short enough to fit vertically in the label. In fact, it could be even larger and still fit if it were properly centered. But I know of no way to center it vertically...
The size of the label can be sized according the length of the string, the font attribute used and the size of the font. I use this method a lot and works great for such requirements -
NSString *textWithinLabel = #"Whatever you like, passed from where ever";
CGSize maximumLabelSize = CGSizeMake(300, 1000); //Place your maximum sizes here
//Here I've used Helvetica, though you can pass any font name or font size here to try out
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:[[UIFont fontWithName:#"Helvetica" size:15] forKey: NSFontAttributeName];
CGSize newExpectedLabelSize = [textWithinLabel boundingRectWithSize:maximumLabelSize options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin attributes:stringAttributes context:nil].size;
CGRect frame = self.yourLabel.frame;
frame.size.height = newExpectedLabelSize.height;
self.yourLabel.frame = frame;
This example will change the height of the label, though you can use it to change width too etc.
The stringAttributes here are used to calculate the size, not to set the attributes. So for example, if your label is using 14pts and you calculate the height for 30pts, it won't change the height of the font, it will only increase the size of the label to accommodate the larger font size. If you want this method to also change the font attributes, you would need to add the appropriate code at the bottom of the method - self.yourLabel.text.font = ... etc.
I hope this answers your question,
Thanks, Jim.
I tried this and it solved my problem. Essentially, the height of the letter is Ascent+Descent. So that's all the space the label needs vertically.
1. [commentLabel sizeToFit]; //To trim out the unwanted area from the label
2. [commentLabel setFrame:CGRectMake(commentLabel.frame.origin.x, commentLabel.frame.origin.y + ABS(commentLabel.font.descender), commentLabel.frame.size.width, commentLabel.font.ascender + ABS(commentLabel.font.descender))];
//The frame adjustment in **(2)**moves the label down by commentLabel.font.descender because the label by default is aligned based on their actual bottom line instead of the actual line we use on notebooks, where the descender hangs down from the line. In case of a label the bottom line is the lower tip of the descender.

Determine UILabel height for centering when using adjustFontSizeToFitWidth

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 :)

Resources