CATextLayer in Interface Builder? - ios

I would like to use a CATextLayer to display some partially bolded text in the form of a NSAttributedString - but would still like to use the convenience of IB for positioning.
Is there a way to drop in a CATextLayer with interface builder? Or what is the next best solution?

You could configure a UIView subclass in IB then set its layerClass to CATextLayer in code:
+ (Class)layerClass;
{
return [CATextLayer class];
}
In the view's init method(s) configure your CATextLayer properties.
To access the layer's properties:
CATextLayer *textLayer = (CATextLayer *)self.layer;
textLayer.string = #"Foo";
// etc...

Related

dynamic font size is not increased for textview?

I am trying to have dynamic font size for the textview.I have mad a custom class for the dynamic font size of text view.I have used following code for the custom class.
#import "CustomTextView.h"
#implementation CustomTextView
- (void)drawRect:(CGRect)rect
{
// Drawing code
int numLines = self.contentSize.height / self.font.lineHeight;
self.font = [UIFont fontWithName:self.font.fontName size:((self.frame.size.height / numLines) - 4)];
[super drawRect: rect];
}
#end
but this does not work.it shows a black color for the textview.please guide how to do it?
There must be something wrong while implementing "CustomTextView.h" in your ViewController.
Let us know how u have done the same.
Share your code in ViewController.
Have you added "CustomTextView" as subview in your view controller.

How to manipulate individual character of UITextView in ios?

I want to manipulate individual character of UITextView like rotating one to the left(90 degrees) and one to the right(90 degrees), and so on.
Anyone has an idea on achieving this?
The easiest thing to modify individual characters in an UITextView is to use NSMutableAttributedString by extending it like this:
#implementation NSMutableAttributedString (Rotation)
- (void)setRotatedFontWithName:(NSString*)fontName
size:(CGFloat)size
range:(NSRange)range
{
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_2);
CTFontRef aFont = CTFontCreateWithName((CFStringRef)fontName, size, &transform);
if (!aFont)
return;
[self removeAttribute:(NSString*)kCTFontAttributeName range:range];
[self addAttribute:(NSString*)kCTFontAttributeName value:(id)aFont range:range];
CFRelease(aFont);
}
And then using the attributedText property of a UITextField to set the rotated font.
What you could also try is creating a custom class that overrides UITextField's default drawRect: and draw the normal and rotated text using Core Text methods (see the example in here, section about rendering text on a curved shape)

Change foregroundColor of a UIView

Is there a way to change the foregroundColor of a UIView?
I'm creating an arrow using an UIView (drawRect) like this ">", with a clear background, only two black lines. This is working great. But afterwards I would like to change the color of the ">" from black to red, for example. Would be nice to have an animation in it, like a gradient from black to red, using CAKeyframeAnimation. I can do it for borderColor and backgroundColor but these properties are not the ones that I'm looking for.
I'm changing the borderColor of another UIView using this block of animation. I would like to do the same with the foregroundColor but it's not working in iOS.
CAKeyframeAnimation* colorAnim = [CAKeyframeAnimation animationWithKeyPath:#"borderColor"];
NSArray* colorValues = [NSArray arrayWithObjects:(id)[UIColor blackColor].CGColor,(id)[UIColor redColor].CGColor, nil];
colorAnim.values = colorValues;
colorAnim.calculationMode = kCAAnimationPaced;
colorAnim.duration = 5.0;
colorAnim.repeatCount = 1;
[self.myView.layer addAnimation:colorAnim forKey:#"borderColor"];
I appreciate any help, thanks!
The UIView class does not have a foregroundColor property, so you have to implement it yourself. In your UIView subclass interface, define the property:
#property (nonatomic, strong) UIColor *foregroundColor;
In your subclass implementation, override the setForegroundColor: setter method:
- (void)setForegroundColor:(UIColor *)newForegoundColor
{
_foregroundColor = newForegroundColor;
[self setNeedsDisplay]; // This is need so that drawRect: is called
}
In whichever initialiser you're are using in the subclass, set the foregroundColor property to a default:
self.foregroundColor = [UIColor blackColor];
In your drawRect: implementation, use the foregroundColor property to stroke the chevron you are drawing:
CGContextSetStrokeColorWithColor(context, self.foregroundColor.CGColor);

How to set the color of the place holder text for a UITextField while preserving its existing properties?

I have seen some answers that show how to change the placeHolder text color for UITextField by overriding the drawPlaceholderInRect: method such as this one:
iPhone UITextField - Change placeholder text color
but that does not maintain the existing attributes such as alignment, font, etc...what is a better way to solve this?
From iOS 6,
Without any subclassing, one can accomplish this with a couple lines of code like so:
UIColor *color = [UIColor blackColor];
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholderText attributes:#{NSForegroundColorAttributeName: color}];
There are multiple ways to achieve this.
Using Interface Builder or Storyboard
Select the Textfield for which you want to change placeholder color
go to the Identity inspector menu on Top right of Xcode
Add the key value pair this way
Key path = _placeholderLabel.textColor
Click the Type and chose Color attribute .
Then select the color in value.
Set The placeholder color using code :
Process 1:
[textField setValue:[UIColor blueColor] forKeyPath:#"_placeholderLabel.textColor"];
Process 2 :
Override drawPlaceholderInRect:(CGRect)rect method
- (void) drawPlaceholderInRect:(CGRect)rect {
[[UIColor blueColor] setFill];
[[self placeholder] drawInRect:rect withFont:[UIFont systemFontOfSize:14]];
}
There is indeed a much better way to handle this now. This will work for iOS 6 and 7.
(Note this example, I created the code in AwakeFromNib since it won't be changing colors once set. But if you don't use XIB, you will have to change the location where you put this code, such as in drawPlaceholderInRect,)
In this example, we create a subclass of UITextField, override awakeFromNib and then set the placeHolder text color to red:
- (void)awakeFromNib
{
if ([self.attributedPlaceholder length])
{
// Extract attributes
NSDictionary * attributes = (NSMutableDictionary *)[ (NSAttributedString *)self.attributedPlaceholder attributesAtIndex:0 effectiveRange:NULL];
NSMutableDictionary * newAttributes = [[NSMutableDictionary alloc] initWithDictionary:attributes];
[newAttributes setObject:[UIColor redColor] forKey:NSForegroundColorAttributeName];
// Set new text with extracted attributes
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:[self.attributedPlaceholder string] attributes:newAttributes];
}
}
The nice thing about this approach is that it maintains the current UITextField properties for the placeHolder string and so will allow you to work in IB for most of what you set. In addition, its much more efficient than doing everytime you need to draw. It also allows you to change any other property you want on the placeHolder text while maintaining the rest of the properties.
As mentioned above, if don't use XIBs, then you will need to call this at some other time. If you do put this code in the drawPlaceholderInRect: method, then make sure you call [super drawPlaceholderInRect:] at the end of it.
The safe way to customize UITextField’s placeholder is subclassing the UITextField and overriding placeholderRectForBounds:, Apple won’t bother you on this one. However, if you want to take the risk, you can try this way:
[self.MyTextField setValue:[UIColor darkGrayColor] forKeyPath:#"_placeholderLabel.textColor"];
Source.

UIControl Lifecycle

Is there a documented Lifecycle for a UIControl somewhere?
Here's why I ask:
Suppose I have a UITextField. I could easily wire up a button that changes the border color like so:
myTextField.layer.borderColor = [[UIColor redColor] CGColor];
Now suppose I have a custom control that's a subclass of UIControl. That same code will not change the border color unless I also issue setNeedsLayout, like so:
[myControl setNeedsLayout];
Is there an event method somewhere that I need to implement to make this work without the setNeedsLayout?
For future generations, here's how I solved the problem on my own.
In my .h file:
#property (nonatomic, strong, setter = setBorderColor:) UIColor *borderColor;
In my .m file:
- (void)setBorderColor:(UIColor *)clr {
borderColor = clr;
myControl.layer.borderColor = borderColor.CGColor;
}
Works like a charm.

Resources