I have the sources of these letters and I am trying to create the gray effect around in objective-c.
But I can not, does anyone have an idea how to do this?
Take a look at GSBorderLabel.
It's good because it adds outer border and not inner border on characters and it's very easy to customise it.
For example:
GSBorderLabel *myLabel = [[GSBorderLabel alloc] initWithFrame:CGRectMake(0, 50, 300, 100)];
myLabel.textColor = [UIColor yellowColor];
myLabel.textAlignment = NSTextAlignmentCenter;
myLabel.borderColor = [UIColor grayColor];
myLabel.borderWidth = 20;
myLabel.text = #"Review";
myLabel.font = [UIFont fontWithName:#"Party LET" size:60.0];
If you're targeting iOS 6 and up, there isn't much over head for this. You can simply use NSAttributedString to add a stroke to an existing font. Mind you, this will not add the stroke to the font, just render it on screen.
NSDictionary *attributes = #{NSStrokeColorAttributeName: [UIColor grayColor], NSStrokeWidthAttributeName : #3};
NSString *inputText = #"Some text";
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:inputText attributes:attributes];
[self.someLabel setAttributedText:attributedString];
You can try this:
#import <QuartzCore/QuartzCore.h>
....
titleLabel.layer.shadowColor = [[UIColor grayColor] CGColor];
titleLabel.layer.shadowRadius = 3;
titleLabel.layer.shadowOpacity = 1;
titleLabel.layer.shadowOffset = CGSizeMake(0, 0);
Related
I am trying to add a stroke to a text and showing in UITextView.
Here is what I want.
In the picture (CREATED FROM PHOTOSHOP) there are same font used, first one has Postion "OUTSIDE" and bottom text has position INSIDE.
I am using following code in Objective-C
NSShadow * shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor blackColor];
shadow.shadowOffset = CGSizeMake(0, 0);
NSDictionary * textAttributes =
#{ NSForegroundColorAttributeName : [UIColor whiteColor],
NSShadowAttributeName : shadow,
NSStrokeColorAttributeName : [UIColor blackColor],
NSStrokeWidthAttributeName : [NSNumber numberWithFloat:-3.0],
NSFontAttributeName : [UIFont fontWithName:#"UbuntuCondensed-Regular" size:40] };
textTitleResult.attributedText = [[NSAttributedString alloc] initWithString:textTitle.text
attributes:textAttributes];
I am achieving INSIDE effect. How can I set position to OUTSIDE
I don't think there's a property that can do exactly when you want. However, I have an idea which will possibly provide you with a way to "fake" it.
You can add another label at the exact position of the original one. The new label would have half the size of the stroke but the stroke color would be the same color as the text. Since the stroke "sits" on the border (half part inside the text and half part outside), it would block half of the original stroke, making it look as if it's on the outside.
Without making the code too pretty, it would look something like this:
UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 40)];
infoLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:infoLabel];
UILabel *secondInfoLabel = [[UILabel alloc] initWithFrame:infoLabel.frame];
secondInfoLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:secondInfoLabel];
NSDictionary * secondTextAttributes =
#{ NSForegroundColorAttributeName : [UIColor whiteColor],
NSStrokeColorAttributeName : [UIColor whiteColor],
NSStrokeWidthAttributeName : [NSNumber numberWithFloat:-3.0],
NSFontAttributeName : [UIFont systemFontOfSize:40] };
secondInfoLabel.attributedText = [[NSAttributedString alloc] initWithString:#"Welcome To" attributes:secondTextAttributes];
NSShadow * shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor blackColor];
shadow.shadowOffset = CGSizeMake(0, 0);
shadow.shadowBlurRadius = 2;
NSDictionary * textAttributes =
#{ NSForegroundColorAttributeName : [UIColor whiteColor],
NSShadowAttributeName : shadow,
NSStrokeColorAttributeName : [UIColor blackColor],
NSStrokeWidthAttributeName : [NSNumber numberWithFloat:-6.0],
NSFontAttributeName : [UIFont systemFontOfSize:40] };
infoLabel.attributedText = [[NSAttributedString alloc] initWithString:#"Welcome To" attributes:textAttributes];
Another option would be to create your own custom view and draw it yourself just the way you want it (in drawRect).
I am trying to set a two line label in my UINavigationBar. When I do the following, it only shows one line (the part before the line break).
NSString *title = #"First line of title is bigger\nSecond line of title is smaller";
NSDictionary *attribute1 = #{NSForegroundColorAttributeName: [UIColor colorWithRed:148/255.0f green:147/255.0f blue:147/255.0f alpha:1],
NSFontAttributeName: [UIFont boldSystemFontOfSize: 14.0f]};
NSDictionary *attribute2 = #{NSForegroundColorAttributeName: [UIColor colorWithRed:148/255.0f green:147/255.0f blue:147/255.0f alpha:1],
NSFontAttributeName: [UIFont boldSystemFontOfSize: 10.0f]};
const NSRange line1Range = {0, 29};
const NSRange line2Range = {31, 30};
NSMutableAttributedString *attributedText =[[NSMutableAttributedString alloc] initWithString:title];
[attributedText setAttributes: attribute1 range:line1Range];
[attributedText setAttributes: attribute2 range:line2Range];
UILabel *label = [[UILabel alloc] init];
label.attributedText=attributedText;
self.navigationItem.titleView = label;
[self.navigationItem.titleView sizeToFit];
For comparison, the following shows both line. The following is for comparison only. The top version is what I need.
UILabel *label = [[UILabel alloc] init];
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 2;
label.font = [UIFont boldSystemFontOfSize: 14.0f];
label.textColor = [UIColor colorWithRed:148/255.0f green:147/255.0f blue:147/255.0f alpha:1];
label.text = #"First line of title is bigger\nSecond line of title is smaller";
self.navigationItem.titleView = label;
[self.navigationItem.titleView sizeToFit];
Any help getting the top version to work correctly?
It appears that calling label.sizeToFit() before self.navigationItem.titleView = label displays the NSAttributedString title correctly.
(Swift, iOS8.1, XCode 6.1.1)
Easy problem, easy solution. Even if you are using attributedText instead of text, you still need to:
label.numberOfLines = 0;
How to display superscript % character as string in UIlabel? I know % does not exist in unicode as a superscript but is there is any way we can display % as a superscript instead of using html tags??
I found this post on Stackoverflow on superscript styling text using attributed string:
NSAttributedString superscript styling
So using that, I hacked up this demo:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIFont *font = [UIFont fontWithName:#"Helvetica" size:20];
UILabel *textBlock1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height / 2.0)];
textBlock1.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
textBlock1.textAlignment = NSTextAlignmentCenter;
textBlock1.font = font;
textBlock1.text = #"57%";
UILabel *textBlock2 = [[UILabel alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height / 2.0, self.view.bounds.size.width, self.view.bounds.size.height / 2.0)];
textBlock2.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
textBlock2.textAlignment = NSTextAlignmentCenter;
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:#"57%"
attributes:#{NSFontAttributeName: font}];
[attributedString setAttributes:#{NSFontAttributeName : [UIFont fontWithName:#"Helvetica" size:10]
, NSBaselineOffsetAttributeName : #10} range:NSMakeRange(2, 1)];
textBlock2.attributedText = attributedString;
[self.view addSubview:textBlock1];
[self.view addSubview:textBlock2];
}
The result:
For a simple to use Swift solution, you might want to checkout HandyUIKit. After importing it into your project (e.g. via Carthage – see instructions in README) you can do something like this:
import HandyUIKit
"57^{%}".superscripted(font: UIFont.systemFont(ofSize: 20, weight: .medium))
This line will return an NSAttributedString which will look exactly like what you're looking for. Just assign it to a UILabels attributedText property and that's it!
If you're looking for subscripting a text, simply use subscripted(font:) instead. It will recognize structures like CO_{2}. There's also superAndSubscripted(font:) if you want to combine both.
See the docs for more information and additional examples.
I'm pretty sure this is actually a UIKit bug but want to get some input to see if I'm missing something silly here.
Here is the code I have:
// single line with modified line spacing and 2 colors - broken, line spacing is added to the bottom!
UILabel *brokenLabel = [[UILabel alloc] init];
brokenLabel.backgroundColor = [UIColor greenColor];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:#"Just some text"];
[attributedString addAttributes:#{NSForegroundColorAttributeName : [UIColor redColor]} range:[attributedString.string rangeOfString:#"text"]];
attributedString = attributedStringFromAttributedStringWithLineSpacing(attributedString, 20, NSTextAlignmentCenter);
brokenLabel.attributedText = attributedString;
[brokenLabel sizeToFit];
brokenLabel.frame = CGRectOffset(brokenLabel.frame, 50, 100);
[self.view addSubview:brokenLabel];
// end
// single line with modified line spacing and 1 color - correct
UILabel *workingLabel = [[UILabel alloc] init];
workingLabel.backgroundColor = [UIColor greenColor];
attributedString = [[NSMutableAttributedString alloc] initWithString:#"Just some text"];
attributedString = attributedStringFromAttributedStringWithLineSpacing(attributedString, 20, NSTextAlignmentCenter);
workingLabel.attributedText = attributedString;
[workingLabel sizeToFit];
workingLabel.frame = CGRectOffset(workingLabel.frame, 200, 100);
[self.view addSubview:workingLabel];
//end
// multiple lines with modified line spacing and 1 color - correct
UILabel *workingLabel2 = [[UILabel alloc] init];
workingLabel2.frame = CGRectMake(0, 0, 100, 0);
workingLabel2.numberOfLines = 0;
workingLabel2.backgroundColor = [UIColor greenColor];
attributedString = [[NSMutableAttributedString alloc] initWithString:#"Just some text"];
attributedString = attributedStringFromAttributedStringWithLineSpacing(attributedString, 20, NSTextAlignmentCenter);
workingLabel2.attributedText = attributedString;
[workingLabel2 sizeToFit];
workingLabel2.frame = CGRectOffset(workingLabel2.frame, 50, 300);
[self.view addSubview:workingLabel2];
//end
// multiple lines with modified line spacing and 2 color - correct
UILabel *workingLabel3 = [[UILabel alloc] init];
workingLabel3.frame = CGRectMake(0, 0, 100, 0);
workingLabel3.numberOfLines = 0;
workingLabel3.backgroundColor = [UIColor greenColor];
attributedString = [[NSMutableAttributedString alloc] initWithString:#"Just some text"];
[attributedString addAttributes:#{NSForegroundColorAttributeName : [UIColor redColor]} range:[attributedString.string rangeOfString:#"text"]];
attributedString = attributedStringFromAttributedStringWithLineSpacing(attributedString, 20, NSTextAlignmentCenter);
workingLabel3.attributedText = attributedString;
[workingLabel3 sizeToFit];
workingLabel3.frame = CGRectOffset(workingLabel3.frame, 200, 300);
[self.view addSubview:workingLabel3];
along with a simple convenience function to change the lineSpacing of an attributed string:
NSMutableAttributedString *attributedStringFromAttributedStringWithLineSpacing(NSAttributedString *string, CGFloat lineSpacing, NSTextAlignment textAlignment)
{
NSMutableAttributedString *mutable = string.mutableCopy;
NSMutableParagraphStyle *par = [NSMutableParagraphStyle new];
par.alignment = textAlignment;
par.lineSpacing = lineSpacing;
[mutable addAttributes:#{NSParagraphStyleAttributeName : par} range:NSMakeRange(0, mutable.length)];
return mutable;
}
However, this is what it looks like
As you can see, the height of the first label is way too big (or the height that it should be + my custom line spacing, to be precise). When simply adding another color to the first attributed string, it causes the sizeToFit size to increase by adding the lineSpacing below it. I also tried using the boundingRectWithSize: methods on the strings directly and the same issue is visible. So this is not specific to the label sizing code but is an issue with the strings themselves. I don't see any possible reason why this should be happening. Does anyone have any insight?
In your Attributes Dictionary add
[attrDic setObject:#0 forKey:NSBaselineOffsetAttributeName];
I use the drawTextInRect: method in the UITextField class to create outlined text (text with a black border/store effect).
But I need something similar to create the same outlined text in a UITextView, but the drawTextInRect: method is not included here. How can I do this for a textView?
This is the code I use in the UITextField class:
- (void)drawTextInRect:(CGRect)rect {
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(c, 1);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetTextDrawingMode(c, kCGTextFill);
self.textColor = [UIColor whiteColor];
[super drawTextInRect:rect];
CGContextSetTextDrawingMode(c, kCGTextStroke);
self.textColor = [UIColor blackColor];
[super drawTextInRect:rect];
}
How can I create a similar solution for a textView in a UITextView class?
Are you targeting iOS 6.0+?
Something like this should work, perhaps:
NSAttributedString *yourString = [[NSAttributedString alloc] initWithString:#"Your text" attributes:#{
NSStrokeColorAttributeName:[UIColor redColor],
NSStrokeWidthAttributeName:[NSNumber numberWithFloat:1.0],
NSFontAttributeName:[UIFont systemFontOfSize:24.0f]
}];
yourTextField.attributedText = yourString;
Enjoy
Peter, use negative value for NSStrokeWidthAttributeName. In this case you can set any fill color for text.
NSAttributedString *yourString = [[NSAttributedString alloc] initWithString:#"Your text" attributes:#{
NSStrokeColorAttributeName:[UIColor redColor],
NSStrokeWidthAttributeName:[NSNumber numberWithFloat:-1.0],
NSFontAttributeName:[UIFont systemFontOfSize:24.0f],
NSForegroundColorAttributeName:[UIColor greenColor]
}];
yourTextField.attributedText = yourString;