Put text in UIView programmatically - ios

Within my app, I use drawRect to draw some text within a UIImage. It writes multiple things in multiple places.. Later, I try to erase some of the text by using
CGContextSetBlendMode(context, kCGBlendModeClear);
CGPoint daPoint = CGPointMake(second.x + 20, second.y + 20);
NSDictionary *textAttributes = #{ NSFontAttributeName: [UIFont boldSystemFontOfSize:25.0],
NSForegroundColorAttributeName: [UIColor clearColor] };
[textString drawAtPoint:daPoint withAttributes:textAttributes];
This works almost perfectly, except there is a small thin stroke left over from the text. I use the same code to draw the text, as I do to erase, except when i'm drawing I use kCGBlendModeNormal. How would I get rid of it completely? Can I draw a box and fill it using kCGBlendModeClear? This is what it looks like currently before erasing:
After erasing:

I would get the bounding rect of the text and then call CGContextClearRect and then fill with the background color if you think that "erasing" the text is really necessary. If you simply "redraw" your rect, that might be another way to solve this problem.
Here's how to get that bounding box for clearing:
CGSize textSize = [textString sizeWithAttributes:textAttributes];
CGRect textFrame = CGRectMake(daPoint.x, daPoint.y, textSize.width, textSize.height);
Hope this helps!

Related

Core Graphics - Is there a way to get/retrieve the currently set CGColor from CGContext?

We can set a CGColor as fill or stroke colour for a given context by doing something like:
UIColor *color = [UIColor whiteColor];
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, color.CGColor);
But how can we get or retrieve currently set fill or stroke colour from a given context?
So is there an API something like:
CGColorRef CGContextGetFillColorFromContext(CGContextRef c)
which takes a CGContext as input parameter and returns it's currently set Fill or stroke CGColour? If not this then is there some other indirect way to achieve this?
I am hoping for the above because the color is set in one class and it is needed back in some other class like so:
In MyView.m
- (void)drawRect:(CGRect)rect {
[[UIColor whiteColor] set]
//[#“Hello” drawInRect:rect withFont:titleFont lineBreakMode:UILineBreakModeCharacterWrap alignment:UITextAlignmentLeft]; //draws text in the rect with white font colour but removed becasue of API deprecation
[#“Hello” my_drawInRect:rect withFont:titleFont lineBreakMode:NSLineBreakByCharWrapping alignment:NSTextAlignmentLeft];
}
In NSString+MyCategory.m
-(void)my_drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(NSLineBreakMode)lineBreakMode alignment:(NSTextAlignment)alignment {
NSMutableParagraphStyle* paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.lineBreakMode = lineBreakMode;
paragraphStyle.alignment = alignment;
UIColor* color = nil; //Hoping to get it from UIGraphicsGetCurrentContext();
[self drawInRect:rect withAttributes:#{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle, NSForegroundColorAttributeName:color}];
}
So is there an API something like
No, there is not, because there doesn't need to be.
But how can we get or retrieve currently set fill or stroke colour from a given context?
The simple answer is that you cannot possibly not know what the currently set color is, because you yourself were the one who set it, as in the line you yourself cite:
CGContextSetFillColorWithColor(ctx, color.CGColor);
If you know you're going to need that color somewhere else, record it in a variable (e.g. an instance variable if the info needs to be available from another method at another time). Plan ahead for your own future needs; that is what programming is.

Draw lines in iOS storyboard similar to Android's XML lines

In Android I can draw lines by simple creating a view and setting its background color
<LinearLayout...>
...
<View android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#color/black"
...
<View android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#color/red"
...
</LinearLayout>
This is a common practice in Android. How might I do the same in iOS? What's the common practice? I see another question here trying to ask a similar question but was told to use a TableView. I am looking for something as simple and as general as the Android answer.
You can create a generic UIView and set its width or height to 1 pt in a storyboard. Set its backgroundColor to what you want the line to be. Make sure you set its constraints or resizing mask so that it doesn't grow in width/height when the screen is resized.
UIView *lineView = [[UIView alloc]init];
lineView.frame = CGRectMake(0,50,self.View.frame.size.width,1);
lineView.backgroundColor = [UIColor blackColor];
[self.view addSubview:lineView];
Take this simple view created in code and just adjust its height by 1 or 2
Just like in the above code -> lineView.frame =CGRectMake(<#CGFloat x#>, <#CGFloat y#>, <#CGFloat width#>, <#CGFloat height#>);
CGFloat height is taken is 1
The same exact thing. Use a UIView with a small width and set its background color to the desired color.
// to draw line in uiview class
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0);
CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);
CGContextMoveToPoint(context, xstartPoint, yStart);
CGContextAddLineToPoint(context, xstartPoint, yBottom);
CGContextStrokePath(context);
CGContextSaveGState(context);

How can I fill a unicode symbol in `drawRect` using Core Graphics?

I know what I want to do, but I'm not sure how to achieve it. I'm new to Core Graphics and I'm not sure this is even possible.
I have a unicode symbol like this: ♖
The white parts of this symbol are transparent and I'm drawing it in a transparent rect like so:
- (void)drawRect:(CGRect)rect
{
NSMutableParagraphStyle *textStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
textStyle.alignment = NSTextAlignmentCenter;
UIFont* myFont = [UIFont fontWithName:#"ArialUnicodeMS" size:80];
NSDictionary *attrs =
#{ NSForegroundColorAttributeName : [UIColor blackColor],
NSFontAttributeName:myFont,
NSParagraphStyleAttributeName:textStyle
};
[[self getStringForValue:_squareValue] drawInRect:rect withAttributes:attrs];
}
What I want is to fill the internal transparent sections with white and leave the surrounding rectangle as transparent.
The approach I'm thinking of is using the unicode symbol as a mask in drawRect to divide the rectangle into regions. Then not filling the region starting at 0,0 but filling all other regions. Can I use Core Graphics to convert the symbol to a mask and then identify and fill specific regions?
What I'm getting at the moment is this:
But what I actually want is this:
You might be able to use -[NSBezierPath appendBezierPathWithGlyph:inFont] and then just set the color to white and call -fill on that path.
EDIT: Since you're on iOS, and I don't know how to get the path of a glyph on iOS, instead I'd just draw the glyph to a buffer that's filled with 100% opaque white, and then do a flood-fill starting from 0,0 with pure transparency.
ANOTHER EDIT: With jrturton's code below, you should be able to trivially do a white fill on the path as originally suggested, then stroke it in black.

Making Glow effect to font

I wonder if anybody have an example for Glow effect for font? I tried to look in NSAttributedString but I don't find in attribute for glowing text.
Try this:
#include <Quartzcore/Quartzcore.h>
.......
yourLabel.layer.shadowColor = [[UIColor glowColor] CGColor]; //Replace glowColor with the desired color (redColor, greenColor, etc.)
yourLabel.layer.shadowOffset = CGSizeMake(0.0, 0.0); //The glow starts from the center
yourLabel.layer.shadowRadius = 20.0; //You can change this to the desired amount
yourLabel.layer.shadowOpacity = 0.5; //You can change this to the desired amount
yourLabel.layer.masksToBounds = NO; //Keep this the same to avoid shadow being clipped by the label bounds
Hope this helps!

Is there a way to have stroke for UIFont

I'm using MKMap with overlay. The overlay display text. I need the text to have "stroke" effect. any clue?
[t drawAtPoint:CGPointMake(0,30) withFont:[UIFont fontWithName:#"Helvetica-Bold" /*"Arial"*/ size:(3 * MKRoadWidthAtZoomScale(zoomScale))]
];
If you're drawing in drawRect:, you can set the text drawing mode using:
CGContextSetTextDrawingMode(UIGraphicsGetCurrentContext(), kCGTextStroke);
If you wanted to fill and stroke, then you can use kCGTextFillStroke.
You can create an CFAttributedString from your string, set appropriate kCTStrokeWidthAttributeName and kCTStrokeColorAttributeName attribute values and draw it with CoreText framework.

Resources