iOS How to draw text in UIViewController - ios

I'm feeling very stupid right now.
I'm trying to draw text onto a UIViewController.
I'm using Xcode 5 and started with a simple Single Page project, and have done nothing else except adding this code to the ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CGRect myRect=CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height);
UIFont *myFont=[UIFont fontWithName:#"Helvetica" size:50];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
paragraphStyle.alignment = NSTextAlignmentRight;
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:myFont forKey:NSFontAttributeName];
[attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
[attributes setObject:[NSNumber numberWithFloat:4] forKey:NSStrokeWidthAttributeName];
[attributes setObject:[UIColor whiteColor] forKey:NSStrokeColorAttributeName];
[#"test" drawInRect:myRect withAttributes:attributes];
// draw fill
[attributes removeObjectForKey:NSStrokeWidthAttributeName];
[attributes removeObjectForKey:NSStrokeColorAttributeName];
[attributes setObject:[UIColor blackColor] forKey:NSForegroundColorAttributeName];
[#"test" drawInRect:myRect withAttributes:attributes];
}
It runs without errors but produces no text - why?

The drawInRect method doesn't work with UIViewController. That method is a UIView method and will only work if your class is a UIView class or subclass.
So, as mentioned above, you can just set your text attributes on a UILabel and display them wherever you like on the screen. It should give you the same effect. Optionally, you could try to change the subclass to UIView, but that could require more modifications to your code than you would like.

To add to tfrank377, you can add labels programmatically with something like
UILabel *addLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 100, 30)];
[self.view addSubview:addLabel];
addLabel.text = #"Hello World";
which will display text on your UIView.

Related

Text Kit not word-wrapping like Core Text with similar settings in UITextView

Using an exclusion path with a UITextView is not properly wrapping the words for the first and last line in the example shown (lower example). It does render properly using word-wrap with CoreText (top example image).
Here is the code for the UITextView (both use the same size bezier path, and both use the same font and paragraph settings)
NSString *testText = #"Text Kit exclusion paths ..."; //text truncated for brevity
UIBezierPath *viewPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 280, 280)];
UIBezierPath *shapePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 10, 265, 265)];
viewPath.usesEvenOddFillRule = true;
shapePath.usesEvenOddFillRule = true;
[shapePath appendPath:viewPath];
NSMutableAttributedString *title = [[NSMutableAttributedString alloc]initWithString:testText];
UIFont *font = [UIFont fontWithName:#"BradleyHandITCTT-Bold" size:14];
[title addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, title.length)];
//add color
[title addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, title.length)];
//add alignment
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setAlignment:NSTextAlignmentCenter];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
[title addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, title.length)];
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 370.0, 280, 280)];
textView.textContainerInset = UIEdgeInsetsMake(0,0,0,0);
textView.textContainer.exclusionPaths = #[shapePath];
[textView.textContainer setLineBreakMode:NSLineBreakByWordWrapping];
textView.contentInset = UIEdgeInsetsMake(0,0,0,0);
textView.attributedText = title;
textView.backgroundColor = [UIColor clearColor];
It is worth noting that the Text Kit is respecting the word wrapping rules except for the first and (possibly last) line where the text does not actually fit. I need this to work with a UITextView because text entry is required, or I would be done with my Core Text example. Swift answers are acceptable as well as obj-c.
How can I make UIKIt behave as it does with Core Text, or in other words properly word wrap all of the words in the example path provided?

IOS drawing text inside a subview

im trying to draw a text on a subview, the view appearing fine but the text not, this is what im doing, the view have black color, the text have white color, text and rect value given in other method:
NSString* sumText = [[NSString alloc]initWithFormat:#"%0.1f",sum];
CGRect textRect = CGRectMake(chartLocation.x+chartLength+10,
chartLocation.y,
20,
20);
[self drawTextRect:sumText inRect:textRect];
-(void)drawTextRect:(NSString *)sumText inRect:(CGRect)textRect {
UIFont* font=[UIFont fontWithName:#"Arial" size:(20/2)];
UIColor* textColor = [UIColor whiteColor];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle]mutableCopy];
paragraphStyle.alignment = NSTextAlignmentCenter;
NSDictionary* stringAttr=#{NSFontAttributeName:font,NSForegroundColorAttributeName:textColor,NSParagraphStyleAttributeName:paragraphStyle};
UIView* textView =[[UIView alloc] initWithFrame:textRect];
textView.backgroundColor = [UIColor blackColor];
[sumText drawInRect:textRect withAttributes:stringAttr];
[self.view addSubview:textView];}
am i do anything wrong? thanks
The drawInRect:withAttributes: method draws the string in the current graphics context. You have not defined a context, so your drawing goes nowhere.
If you want to draw the string yourself, you should subclass UIView, add the required properties (sumText), and overwrite drawRect:. A graphics context is automatically created for you in drawRect: so you can just go ahead and draw.
But really, you probably just want to use a UILabel instead.
there is another way you can achieve what you want .
UILabel* lblText = [[UILabel alloc]initWithFrame:CGRectMake(50, 50, 200, 200)];
lblText.text = #"Hello World!";
lblText.backgroundColor = [UIColor blackColor];
lblText.textColor = [UIColor whiteColor];
[self.view addSubview:lblText];
And Output is:

Update NSMutableAttributedString in another class

I have a UIButton class with a NSMutableAttributedString as the title (for the formatting).
I would like to now change the titleColor of the button text from my vc class because it has been'selected'.
I can do it fine as a normal button title. But as a NSMutableAttributedString - no dice.
Some questions/advice: As the custom class view is already a button - should my color update happen in that class - and not from the vc? Just tell it to update and bake the color in the custom class?
Do I expose the NSMutableAttributedString property for the button's title so that I can access from my VC and change the color? This way I could also pass in new text as well as a new color.
In my CircleButton m file
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSTextAlignmentCenter];
[style setLineBreakMode:NSLineBreakByWordWrapping];
UIFont *font1 = [UIFont fontWithName:#"Futura" size:20.0f];
NSDictionary *dict1 = #{NSUnderlineStyleAttributeName:#(NSUnderlineStyleNone),
NSFontAttributeName:font1,
NSForegroundColorAttributeName:textClr,
NSParagraphStyleAttributeName:style};
attributedTText = [[NSAttributedString alloc] initWithString:btnTxt attributes:dict1];
[[button titleLabel] setNumberOfLines:0];
[[button titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
[button setAttributedTitle:attributedTText forState:UIControlStateNormal];
[button setTitleColor:textClr forState:UIControlStateNormal];

Setting attributedText of UILabel causing issue with Lengthier content

In my project I want to add an attributed text in UILabel placed on the xib.
It's working perfectly, but if large text appears it shows some issues.
My current implementation:
- (void)viewDidLoad
{
[super viewDidLoad];
_demoLabel.numberOfLines = 0;
_demoLabel.lineBreakMode = NSLineBreakByWordWrapping;
_demoLabel.attributedText = [self demoNameWithFontSize:21 andColor:[UIColor redColor]];
}
- (NSMutableAttributedString *)demoNameWithFontSize:(CGFloat)fontSize andColor:(UIColor *)color
{
NSMutableAttributedString *attributedText = nil;
NSString *demoName = #"Blah blah blah";
UIFont *demoFont = [UIFont fontWithName:#"Zapfino" size:fontSize];
attributedText = [[NSMutableAttributedString alloc] initWithString:demoName];
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.lineBreakMode = NSLineBreakByWordWrapping;
[attributedText addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, [demoName length])];
[attributedText addAttribute:NSFontAttributeName value:demoFont range:NSMakeRange(0, [demoName length])];
[attributedText addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, [demoName length])];
return attributedText;
}
Output:
Issue:
It is not displaying the whole text, even if I applied the NSMutableParagraphStyle.
How can I solve this ?
Alternative I found:
If I change
UIFont *demoFont = [UIFont fontWithName:#"Zapfino" size:fontSize];
to
UIFont *demoFont = [UIFont systemFontOfSize:fontSize];
It'll work and gives output like:
But the issue is I need to use custom font, can't use default font. Also cannot change the font size.
I checked UILabel class reference and googled, but couldn't find a solution. Please help me.
Is there anyway to span this text into multiple lines ?
You need to resize the UILabel to fit the text.
You can calculate the size with the boundingRectWithSize:options:context: NSAttributedString class method, which takes an attributed string and calculates the size within a set rect based on all the attributes of the string.

UITextField underlines from NSAttributedString are only 1 pixel high?

The label (bottom of the picture) and the text field (top) have the same same attributedText. But look at the underlines. The ones in the text field are only one pixel high. This looks terrible. Does anyone know what is causing this or how to prevent it?
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UITextField* textField = [[UITextField alloc]initWithFrame:CGRectMake(100, 100, 600, 200)];
NSMutableAttributedString* string = [[NSMutableAttributedString alloc]initWithString:#"The quick brown fox jumps"];
NSNumber* underlineNumber = [NSNumber numberWithInteger:NSUnderlineStyleSingle];
UIFont* font = [UIFont systemFontOfSize: 50];
[string addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, string.length)];
for (NSInteger i=0; i<20; i++) {
if (i%3==0) {
[string addAttribute:NSUnderlineStyleAttributeName value:underlineNumber range:NSMakeRange(i, 1)];
}
}
textField.backgroundColor = [UIColor whiteColor];
textField.attributedText = string;
[self addSubview:textField];
UILabel* label = [[UILabel alloc]initWithFrame:CGRectMake(100, 400, 600, 200)];
label.attributedText = string;
label.font = font;
label.backgroundColor = [UIColor whiteColor];
[self addSubview:label];
}
return self;
}
The label uses a custom rendering style to draw the underline which is unfortunately distinct from the one used by UITextField, which uses WebKit to render when editing and Core Text to render when it's static. Please file a bug with bugreporter.apple.com. Thanks!

Resources