I have SVG file and i was able to access SVG's shapes using SVGKit.
Now, I have CAShapeLayer which may contain circle, square or any closed shape.
I want to add CATextLayer on CAShapeLayer in such way that text should not cross the defined shape.
Here is the example of crossing CATextLayer on CAShapeLayer :
It's crossing just because, CATextLayer is starting from 0 position of CAShapeLayer which contains circle in particular this case.
In my case, CAShapeLayer can contain any closed shape. It can be oval also.
How can I identify shape inside CAShapeLayer? or How can I apply path to CATextLayer? which will makes sure text will be drawn inside shape?
Here is code to add CATextLayer On CAShapeLayer:
-(CATextLayer *)addTrackerNumberToLayer:(NSString *)numbers{
self.numbersTextLayer = [CATextLayer new];
self.numbersTextLayer.foregroundColor = [UIColor blackColor].CGColor;
self.numbersTextLayer.font = (__bridge CFTypeRef _Nullable)([UIFont boldSystemFontOfSize:15]);
self.numbersTextLayer.fontSize=25;
self.numbersTextLayer.anchorPoint = CGPointZero;
self.numbersTextLayer.frame = CGRectMake(self.parentShapeLayer.bounds.size.width*0.05, self.parentShapeLayer.bounds.size.height*0.05, self.parentShapeLayer.bounds.size.width*0.90, self.parentShapeLayer.bounds.size.height*0.30);
self.numbersTextLayer.position = CGPointMake(self.parentShapeLayer.bounds.size.width*0.05,self.parentShapeLayer.bounds.size.height*0.05);
self.numbersTextLayer.alignmentMode = kCAAlignmentCenter;
[self.parentShapeLayer addSublayer:self.numbersTextLayer];
}
Use isWrapped property of CATextLayer this determines whether the text is wrapped to fit within the receiver’s bounds.
-(CATextLayer *)addTrackerNumberToLayer:(NSString *)numbers{
self.numbersTextLayer = [CATextLayer new];
self.numbersTextLayer.foregroundColor = [UIColor blackColor].CGColor;
self.numbersTextLayer.font = (__bridge CFTypeRef _Nullable)([UIFont boldSystemFontOfSize:15]);
self.numbersTextLayer.fontSize=25;
self.numbersTextLayer.anchorPoint = CGPointZero;
self.numbersTextLayer.frame = CGRectMake(self.parentShapeLayer.bounds.size.width*0.05, self.parentShapeLayer.bounds.size.height*0.05, self.parentShapeLayer.bounds.size.width*0.90, self.parentShapeLayer.bounds.size.height*0.30);
self.numbersTextLayer.position = CGPointMake(self.parentShapeLayer.bounds.size.width*0.05,self.parentShapeLayer.bounds.size.height*0.05);
self.numbersTextLayer.alignmentMode = kCAAlignmentCenter;
[self.numbersTextLayer setWrapped:YES];//User Wrapped to YES to imbound the text to fit in the region.
[self.parentShapeLayer setMasksToBounds:YES];
[self.parentShapeLayer addSublayer:self.numbersTextLayer];
return self.numbersTextLayer;
}
Related
I have a UIImageView in which I have a UIImage obviously. I want to create a shadow effect only on the UIImage. My problem is that I cannot get the CGRect of the UIImage inside the UIImageView so I can apply the shadow effect on it by using the following method.
[mImageView.layer.shadowColor = [UIColor grayColor].CGColor;
mImageView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
mImageView.layer.shadowOpacity = 0.9f;
mImageView.layer.masksToBounds = NO;
CGRect imageFrame = mImageView.frame;
UIEdgeInsets shadowInsets = UIEdgeInsetsMake(0, 0, -1.5f, 0);
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:UIEdgeInsetsInsetRect(imageFrame, shadowInsets)];
mImageView.layer.shadowPath = shadowPath.CGPath;
Please consider the image attached for this problem.
The problem is critical too because the UIImage can be an image of a rigid dimension because it is a cropped image as you can see in the picture attached.
The UIImageView’s bound is equal to the view’s bound here. So when applying the effect using the method above, it creates a UIBezierPath on the whole UIImageView, not only to the UIImage. As in the method, I cannot get the exact CGRect of the UIImage.
Any solution? What am I missing?
cropped image
UIImage is always rectangular, so is UIImageView. I believe you want to put shadow only around the jagged border of the cropped area right? If that is the case, you cannot use this method. You need to use CoreGraphics or others, to get the effect you want. For example, you can create a copy of this image in memory, blackened it, and blur it and paste it behind your image to create a shadowy effect.
Lets say i have a an image (a semi-circle gauge) with colors starting from green to yellow to red. How can i programmatically clip and fill the image for a given percentage dynamically using CoreGraphics/Quartz ?
You can use a CALayer with a custom mask.
The mask will be a CAShapeLayer with a path that defines the given percentage of the guage.
CALayer *guageLayer = //your CALayer, could be the backing view
CAShapeLayer *guageMask = [[CAShapeLayer alloc] init];
guageMask.path = [self _pathForCurrentGuage]; //bezier path based on your current percentage
guageLayer.mask = guageMask;
I want to set a Dotted / Dashed border for my UITextField and UITextView.
How can I do that? I know that, I can set border with this line of code:
[self.textFieldCardTitle.layer setBorderWidth:1.0];
[self.textFieldCardTitle.layer setBorderColor:[[UIColor whiteColor] CGColor]];
Notice: I already have the idea to add a UIImageView behind the UITextView and set there an image with dashed border. But I don't want to solve it that way.
You could try, for example, next approach:
1) Create image that will represent your border (for example: one dot and space)
2) Add image to project.
3) Set border (as in code in your question) and set color with pattern:
[self.textFieldCardTitle.layer setBorderWidth:6.0];
[self.textFieldCardTitle.layer setBorderColor:[[UIColor colorWithPatternImage:[UIImage imageNamed:#"dashed_white.png"]] CGColor]];
As border is drawn along 4 sides (left, right, bottom, top) you should use square image: for example, pixel in middle is black and pixels around it are transparent. So copies of that image will be placed around the view.
Just use following code for Dotted / Dashed Border around UIView or UITextField or any other view:-
CAShapeLayer * _border = [CAShapeLayer layer];
_border.strokeColor = [UIColor redColor].CGColor;
_border.fillColor = nil;
_border.lineDashPattern = #[#4, #2];
[YOURVIEW.layer addSublayer:_border];
//for a square effect
_border.path = [UIBezierPath bezierPathWithRect:YOURVIEW.bounds].CGPath;
//for a rounded effect
//_border.path = [UIBezierPath bezierPathWithRoundedRect:YOURVIEW.bounds cornerRadius:txtUserName.frame.size.height / 2].CGPath;
_border.frame = YOURVIEW.bounds;
For more details, Refer this Answer.
Hope, this is what you're looking for. Any concern get back to me. :)
Here's what I did with Swift:
self.textFieldCardTitle.layer.borderWidth = 3
self.textFieldCardTitle.layer.borderColor = (UIColor(patternImage: UIImage(named: "dot")!)).CGColor
Free bonus, I attached the pics below. Unless StackOverflow changes its background, you probably won't see them as they are white squares on a white background, so you'll find the urls below as well.
http://i.stack.imgur.com/X7PfM.png -> rename it to dot.png
http://i.stack.imgur.com/IemhF.png -> rename it to dot#2x.png
http://i.stack.imgur.com/CSjZT.png -> rename it to dot#3x.png
Swift 5, for #Meet Doshi's answer
class CustomTextField: UITextField{
let dashBorder = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: .zero)
dashBorder.strokeColor = UIColor.lightGray.cgColor
dashBorder.fillColor = nil
dashBorder.lineDashPattern = [4, 2]
layer.addSublayer(dashBorder)
}
override func layoutSubviews() {
super.layoutSubviews()
dashBorder.path = UIBezierPath(roundedRect: bounds, cornerRadius: 5).cgPath
dashBorder.frame = bounds
}
}
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!
How can I set label's border which is dynamically generated (Not from Interface Builder)?
you can do it by
Label.layer.borderColor = [UIColor whiteColor].CGColor;
Label.layer.borderWidth = 4.0;
before this you need to import a framework QuartzCore/QuartzCore.h
Swift version
Set label border
label.layer.borderWidth = 2.0
Set border color
label.layer.borderColor = UIColor.blueColor().CGColor
Use rounded corners
label.layer.cornerRadius = 8
Make background color stay within rounded corners
label.layer.masksToBounds = true
You can also try to subclass your label and override the drawRect: method to draw or a border or whatever you like:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor blackColor] setStroke];
CGContextStrokeRect(context, self.bounds);
}
I'm not sure you can by default with UILabel. You might want to consider using a read-only (field.editing = NO) UITextField and setting it's borderStyle (which can be done programmatically using a UITextBorderStyle). That may be a little 'heavy' though. Another option may be to sub-class UILabel to draw your border.
Alternatively, and depending on your needs this may be better, use the backing CALayer and draw a border using it's borderColor and borderWidth properties.