kCTUnderlineStyleSingle is not working for some character - ios

I am using NSAttributedstring with the attribute kCTUnderlineStyleSingle.
Character is underlining properly. But some character like g, q, p are not visible properly.
Even user cannot differentiate between g and q.
Is there any solution for that?

You can fix it using this method:
- (void)addUnderlineWithRange:(NSRange)range
{
int lineThickness = [EnvUtils isIpadEnv] ? 2 : 1;
UIColor *lineColor = self.textColor;
NSString *string = self.text;
CGRect labelFrame = self.frame;
CGSize expectedLabelSize = [NSString getMultilineTextSize:[string substringWithRange:range] forMaxSize:labelFrame.size font:self.font];
CGSize expectedLabelFullSize = [NSString getMultilineTextSize:string forMaxSize:labelFrame.size font:self.font];
CGSize xOffset = [NSString getMultilineTextSize:[string substringWithRange:NSMakeRange(0, range.location)] forMaxSize:labelFrame.size font:self.font];
CGFloat originX = (labelFrame.size.width - expectedLabelFullSize.width) / 2 + xOffset.width;
CGFloat originY = expectedLabelSize.height + (labelFrame.size.height - expectedLabelFullSize.height) / 2;
CGRect lineFrame = CGRectMake(originX, originY, expectedLabelSize.width, lineThickness);
UIView *lineView = [[[UIView alloc] initWithFrame:lineFrame] autorelease];
lineView.backgroundColor = lineColor;
[self.superview addSubview:lineView];
}

Related

UILabel Pixelated on Zoom in iOS App

I have a UILabel which added in UIView and this view add as subview of UIScrollViewand zooming is enabled. Working every thing fine but when I zoom in then UILabel and other properties too and this look quite odd.I also added following code for flexible size.
userResizableView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
userResizableView.autoresizesSubviews = YES;
Above View is `UIView Type.
And below is code of Label
UILabel * lbl_FormFieldName = [[UILabel alloc]initWithFrame:CGRectMake(1, 1, rect.size.width, 15)];
lbl_FormFieldName.attributedText = attrText;
// lbl_FormFieldName.text = text;
lbl_FormFieldName.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
lbl_FormFieldName.textColor = [UIColor blackColor];
lbl_FormFieldName.backgroundColor = [UIColor clearColor];
lbl_FormFieldName.font = customFont;
lbl_FormFieldName.numberOfLines = 0;
lbl_FormFieldName.baselineAdjustment = UIBaselineAdjustmentAlignBaselines; // or UIBaselineAdjustmentAlignCenters, or UIBaselineAdjustmentNone
lbl_FormFieldName.clipsToBounds = YES;
lbl_FormFieldName.textAlignment = NSTextAlignmentCenter;
Kindly give me any suggestion how to make good. Looking for suggestion.
Thanks
Maybe the frame label is using floating numbers. Try this to force integers value for your frame:
[label setFrame:CGRectIntegral(label.frame)];
As per my requirement I have added pinch gesture on uilabel like this :
1. Add this line before implementation.
CG_INLINE CGRect CGRectScale(CGRect rect, CGFloat wScale, CGFloat hScale)
{
return CGRectMake(rect.origin.x * wScale, rect.origin.y * hScale, rect.size.width * wScale, rect.size.height * hScale);
}
2. Add gesture on label
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(viewDidPinch:)];
pinch.delegate =self;
[self addGestureRecognizer:pinch];
3. Add method in your file. Add scrollview bounds instead of self.bounds as I have different scenario in my case.
- (void)viewDidPinch:(UIPinchGestureRecognizer*)sender
{
CGFloat scale = sender.scale;
CGRect scaleRect = CGRectScale(self.bounds, scale, scale);
if (scaleRect.size.width >= 5 && scaleRect.size.height >= 5) {
[self._label setAttributedText:[self getScaledStringFrom:self._label.attributedText withScale:scale]];
[self._label setFrame:self.bounds];
}
sender.scale=1.0;
}
4. Rewrite text with new scale
- (NSMutableAttributedString*) getScaledStringFrom:(NSMutableAttributedString*)string withScale:(CGFloat)scale
{
[string beginEditing];
[string enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, string.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
if (value) {
UIFont *oldFont = (UIFont *)value;
UIFont *newFont = [oldFont fontWithSize:oldFont.pointSize * scale];
[string removeAttribute:NSFontAttributeName range:range];
[string addAttribute:NSFontAttributeName value:newFont range:range];
}
}];
[string endEditing];
return string;
}

Display the UILabel verticallly from the NSMutableArray inside the UIView

I have a list of array objects which I pass into to a loop and display it as UILabel dynamically. However I need the values to display it in a vertical. Below are my code,
labelArrays = [NSMutableArray arrayWithObjects:#"One”, #“Two”, #“Three",#"four",#"five",#"six" ,nil];
//inside a method with a loop am passing the array and creating the labels.
-(void) createlabel:(CGRect) frame{
float xCoordinate = frame.origin.x;
float yCoordinate = frame.origin.y;
int labelHeight =30;
int gapBetweenTwoLabels =2;
int labelWidth = 100;
for(int counter = 0; counter < [labelArrays count]; counter++){
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(xCoordinate,yCoordinate,labelWidth,labelHeight)];
label.text = [labelArrays objectAtIndex:counter];
[self addSubview:label];
xCoordinate = xCoordinate + labelWidth + gapBetweenTwoLabels;
}
}
//frame
[self createlabel:CGRectMake(25,130,100,40)];
This displays me as
one two three four five six
but i need it as
one two three
four five six
can anyone suggest me how can i achieve it? Note: I use this method inside the UIView not in the controller.
Change your y-coordinate as #Larme mentioned
labelArrays = [NSMutableArray arrayWithObjects:#"One”, #“Two”, #“Three", #"four", #"five", #"six" ,nil];
If you want output as following
one
two
three
four
five
six
-(void) createlabel:(CGRect) frame {
CGFloat xCoordinate = frame.origin.x;
CGFloat yCoordinate = frame.origin.y;
CGFloat labelHeight = frame.size.height;
CGFloat labelWidth = frame.size.width;
CGFloat gapBetweenTwoLabels = 2;
for(int counter = 0; counter < [labelArrays count]; counter++) {
UILabel *label = [[UILabel alloc]initWithFrame : CGRectMake(xCoordinate, yCoordinate, labelWidth, labelHeight)];
label.text = [labelArrays objectAtIndex:counter];
[self addSubview:label];
yCoordinate = yCoordinate + labelHeight + gapBetweenTwoLabels;
}
}
But if you want output as :
one
two
three
four
five
six
-(void) createlabel:(CGRect) frame {
CGFloat xCoordinate = frame.origin.x;
CGFloat yCoordinate = frame.origin.y;
CGFloat labelHeight = frame.size.height;
CGFloat labelWidth = frame.size.width;
CGFloat gapBetweenTwoLabels = 2;
for(int counter = 0; counter < [labelArrays count]; counter++) {
UILabel *label = [[UILabel alloc]initWithFrame : CGRectMake(xCoordinate, yCoordinate, labelWidth, labelHeight)];
label.text = [labelArrays objectAtIndex:counter];
[self addSubview:label];
if((counter+1)%3 == 0) {
xCoordinate = 0;
yCoordinate = yCoordinate + labelHeight + gapBetweenTwoLabels;
} else {
xCoordinate = xCoordinate + labelWidth + gapBetweenTwoLabels;
}
}
}
Function call
[self createlabel:CGRectMake(25,130,100,40)];

Integer and string won't right pad.. Objective C

The code is below. What ends up happening is it's as if I used leftPadding instead of rightPadding and a string or long integer will run of the screen to the right. What I want is for the string is pad itself on the right and it's length extends to the left..
- (void)constructTimeStampLabel {
CGFloat rightPadding = 250.f;
CGFloat topPadding = -30.f;
CGRect frame = CGRectMake(rightPadding,
topPadding,
floorf(CGRectGetWidth(__informationView.frame)),
CGRectGetHeight(__informationView.frame) - topPadding);
_timeStampLabel = [[UILabel alloc] initWithFrame:frame];
_timeStampLabel.text = [NSString stringWithFormat:#"Sent on %#", _feedItem.timeStamp];
_timeStampLabel.textColor = [UIColor whiteColor];
[_timeStampLabel setFont:[UIFont systemFontOfSize:12]];
[__informationView addSubview:_timeStampLabel];
}
try setting the alignment to the right.
_timeStampLabel.textAlignment = NSTextAlignmentRight;

UITextView contentsize.height issue in iOS 7

I searched & spend so much time to resolve the issue of content size height, but it’s hard luck, nothing worked. Similar questions are available in stack & other forums also but i am not getting what is left, which is not allowing my textview to resolve this issue.
I have to place textView’s cursor & text at centre of it’s width & height. Now i use it-
UITextView *tv = object;
[tv setScrollEnabled:YES];
CGFloat height = [tv bounds].size.height;
CGFloat contentheight;
contentheight = [tv sizeThatFits:CGSizeMake(tv.frame.size.width, FLT_MAX)].height;
NSLog(#"iOS7; %f %f", height, contentheight);
// [tv sizeToFit];
CGFloat topCorrect = height - contentheight;
topCorrect = (topCorrect <0.0 ? 0.0 : topCorrect);
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
[tv setScrollEnabled:NO];
The Second Approach i used is-
#pragma mark- UITextView ContentHeight Messurment
- (CGFloat)measureHeightOfUITextView:(UITextView *)textView
{
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
{
// This is the code for iOS 7. contentSize no longer returns the correct value, so
// we have to calculate it.
//
// This is partly borrowed from HPGrowingTextView, but I've replaced the
// magic fudge factors with the calculated values (having worked out where
// they came from)
CGRect frame = textView.bounds;
// Take account of the padding added around the text.
UIEdgeInsets textContainerInsets = textView.textContainerInset;
UIEdgeInsets contentInsets = textView.contentInset;
CGFloat leftRightPadding = textContainerInsets.left + textContainerInsets.right + textView.textContainer.lineFragmentPadding * 2 + contentInsets.left + contentInsets.right;
CGFloat topBottomPadding = textContainerInsets.top + textContainerInsets.bottom + contentInsets.top + contentInsets.bottom;
frame.size.width -= leftRightPadding;
frame.size.height -= topBottomPadding;
NSString *textToMeasure = textView.text;
if ([textToMeasure hasSuffix:#"\n"])
{
textToMeasure = [NSString stringWithFormat:#"%#-", textView.text];
}
// NSString class method: boundingRectWithSize:options:attributes:context is
// available only on ios7.0 sdk.
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
NSDictionary *attributes = #{ NSFontAttributeName: textView.font, NSParagraphStyleAttributeName : paragraphStyle };
CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
CGFloat measuredHeight = ceilf(CGRectGetHeight(size) + topBottomPadding);
return measuredHeight;
}
else
{
return textView.contentSize.height;
}
}
The response is coming like it-
After editing it, it's appearing like it-
Now, what else i can try to put textView's text on the centre of UITextView? Please update me.

MBProgressHUD to show label text in more than one line

Hi i have a MBProgressHUD on my iPad screen. Works perfectly fine. But i want to change the label to show in three lines.Like this
self.hud = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
self.hud.frame = CGRectMake(0, 0, 120, 143);
[self.navigationController.view addSubview:self.hud];
self.hud.delegate = self;
self.hud.mode = MBProgressHUDModeAnnularDeterminate;
NSString *strloadingText = [NSString stringWithFormat:#"Loading Data.\r Please Wait.\r 1-2 Minutes"];
NSLog(#"the loading text will be %#",strloadingText);
self.hud.labelText = strloadingText;
[self.hud show:YES];
So i want the label in 3 lines
Loading Data.
Please Wait
1-2 Minutes
OR
can i assign an image to the HUD?
All this should be in the labeltext. But i am ending up with only one line. How can i do that?
If you need more info, please ask.Thanks.
MBProgressHUD's detailsLabelText property is multiline but not labelText property.
So, you can try something like this
MBProgressHUD * hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.frame = CGRectMake(0, 0, 120, 143);
hud.mode = MBProgressHUDModeAnnularDeterminate;
NSString *strloadingText = [NSString stringWithFormat:#"Loading Data."];
NSString *strloadingText2 = [NSString stringWithFormat:#" Please Wait.\r 1-2 Minutes"];
NSLog(#"the loading text will be %#",strloadingText);
hud.labelText = strloadingText;
hud.detailsLabelText=strloadingText2;
You can set detailsLabelText font by using the property detailsLabelFont.
I had a question like this, too !
You can set hud.label.numberOfLines = 0;
And it works!
The reason why labelText differs from detailsText, I imagine because it's meant to be a very similar to UIAlertView from the title/description perspective.
The differences between the two labels is quite distinct because of their purpose, for instance:
Titles have bigger fonts, oft times bold in comparison to detail text.
Titles are meant to be short and obvious, taken from a popular dictionary site (description speaks for itself):
Title: A descriptive name; an epithet.
I'd recommend not having a multi-line title, keeping it short, and using the description text.
The reason why multi-line titles do not work is because of the layoutSubviews implementation, the size is not being calculated. if you inspect MBProgressHud.m, within layoutSubviews,
CGFloat remainingHeight = bounds.size.height - totalSize.height - kPadding - 4 * margin;
CGSize maxSize = CGSizeMake(maxWidth, remainingHeight);
CGSize detailsLabelSize = [detailsLabel.text sizeWithFont:detailsLabel.font
constrainedToSize:maxSize lineBreakMode:detailsLabel.lineBreakMode];
totalSize.width = MAX(totalSize.width, detailsLabelSize.width);
totalSize.height += detailsLabelSize.height;
if (detailsLabelSize.height > 0.f && (indicatorF.size.height > 0.f || labelSize.height > 0.f)) {
totalSize.height += kPadding;
}
Note the -[NSString sizeWithFont: constrainedToSize: lineBreakMode:] call for the description text; this method calculates the size required to display the text - using as many lines as necessary, whereas the -[NSString sizeWithFont:] calculates the size required to display the text, but only up to displaying one line.
I would advise against having a multi-line title, and instead provide a shorter title, with some description text to accompany it.
If you simply must have the multi-line title (all changes within MBProgressHud.m):
- (void)setupLabels {
label = [[UILabel alloc] initWithFrame:self.bounds];
label.adjustsFontSizeToFitWidth = NO;
label.textAlignment = MBLabelAlignmentCenter;
label.opaque = NO;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.font = self.labelFont;
label.text = self.labelText;
>>> label.numberOfLines = 0;
[self addSubview:label];
...
Replace:
CGSize labelSize = [label.text sizeWithFont:label.font];
labelSize.width = MIN(labelSize.width, maxWidth);
totalSize.width = MAX(totalSize.width, labelSize.width);
totalSize.height += labelSize.height;
if (labelSize.height > 0.f && indicatorF.size.height > 0.f) {
totalSize.height += kPadding;
}
CGFloat remainingHeight = bounds.size.height - totalSize.height - kPadding - 4 * margin;
CGSize maxSize = CGSizeMake(maxWidth, remainingHeight);
CGSize detailsLabelSize = [detailsLabel.text sizeWithFont:detailsLabel.font
constrainedToSize:maxSize lineBreakMode:detailsLabel.lineBreakMode];
With:
CGFloat remainingHeight = bounds.size.height - totalSize.height - kPadding - 4 * margin;
CGSize maxSize = CGSizeMake(maxWidth, remainingHeight);
CGSize labelSize = [label.text sizeWithFont:label.font constrainedToSize:maxSize lineBreakMode:label.lineBreakMode];
totalSize.width = MAX(totalSize.width, labelSize.width);
totalSize.height += labelSize.height;
if (labelSize.height > 0.f && indicatorF.size.height > 0.f) {
totalSize.height += kPadding;
}
remainingHeight = bounds.size.height - totalSize.height - kPadding - 4 * margin;
CGSize detailsLabelSize = [detailsLabel.text sizeWithFont:detailsLabel.font
constrainedToSize:maxSize lineBreakMode:detailsLabel.lineBreakMode];
Hope this isn't too late to help.
self.hud.minSize = CGSizeMake(300, 100);

Resources