How to add text shadows to a UITextView? - objective-c

I've been searching around to find an easy way to add shadows to the text of a UITextView, like you can do in a UILabel. I found this question where there was an answer that supposedly does this, however, it makes no sense why this should be the case.
Question: Adding shadows to the layer of the UITextView itself should not affect the text inside, rather it should shadow the entire object, right?
In my case, even adding the shadow to the layer of the textview is not having any effect (even after adding the QuartzCore headers).

i tried, and found that , you should set the UITextView's backgroundcolor to transparent,
so the shadow should work
UITextView *text = [[[UITextView alloc] initWithFrame:CGRectMake(0, 0, 150, 100)] autorelease];
text.layer.shadowColor = [[UIColor whiteColor] CGColor];
text.layer.shadowOffset = CGSizeMake(2.0f, 2.0f);
text.layer.shadowOpacity = 1.0f;
text.layer.shadowRadius = 1.0f;
text.textColor = [UIColor blackColor];
//here is important!!!!
text.backgroundColor = [UIColor clearColor];
text.text = #"test\nok!";
text.font = [UIFont systemFontOfSize:50];
[self.view addSubview:text];

#adali's answer will work, but its wrong. You shouldn't add the shadow to the UITextView itself in order to effect the visible views inside. As you can see, by applying the shadow to the UITextView the cursor will also have the shadow.
The approach that should be used is with NSAttributedString.
NSMutableAttributedString* attString = [[NSMutableAttributedString alloc] initWithString:textView.text];
NSRange range = NSMakeRange(0, [attString length]);
[attString addAttribute:NSFontAttributeName value:textView.font range:range];
[attString addAttribute:NSForegroundColorAttributeName value:textView.textColor range:range];
NSShadow* shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor whiteColor];
shadow.shadowOffset = CGSizeMake(0.0f, 1.0f);
[attString addAttribute:NSShadowAttributeName value:shadow range:range];
textView.attributedText = attString;
However textView.attributedText is for iOS6. If you must support lower versions, you could use the following approach.
CALayer *textLayer = (CALayer *)[textView.layer.sublayers objectAtIndex:0];
textLayer.shadowColor = [UIColor whiteColor].CGColor;
textLayer.shadowOffset = CGSizeMake(0.0f, 1.0f);
textLayer.shadowOpacity = 1.0f;
textLayer.shadowRadius = 0.0f;

Related

Add padding into UIlabel text?

I've a label in a table cell and I wish to add padding to top,bottom,left and right.
CGRect initialFrame = CGRectMake(10,10,100,20);
UIEdgeInsets contentInsets = UIEdgeInsetsMake(5, 0, 5, 0);
CGRect padd = UIEdgeInsetsInsetRect(initialFrame, contentInsets);
self.rewardLabel = [[UILabel alloc] initWithFrame:padd];
self.rewardLabel.backgroundColor =[UIColor colorWithRed:0.192 green:0.373 blue:0.561 alpha:1];
self.rewardLabel.layer.cornerRadius = 5.0f;
self.rewardLabel.layer.masksToBounds = YES;
self.rewardLabel.textColor = [UIColor whiteColor];
self.rewardLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.rewardLabel.numberOfLines = 1;
self.rewardLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:14];
[self.contentView addSubview:self.rewardLabel];
But it seem like not working. Can anyone tell me how to do?
There are several ways on how to achieve this:
If you do not need a specific background color for your label you could just adjust the labels frame to add the padding (e.g. if your text should start 20px from the cell's left side, set the label's frame's x to 20).
To really add a padding, you could use a custom UILabel subclass and override its drawTextInRect: and intrinsicContentSize methods. (See this question for details)
If you just need a left and right padding you could use an NSAttributedString to add insets to UILabel:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.headIndent = 5.0;
paragraphStyle.firstLineHeadIndent = 5.0;
paragraphStyle.tailIndent = -5.0;
NSDictionary *attrsDictionary = #{NSParagraphStyleAttributeName: paragraphStyle};
label.attributedText = [[NSAttributedString alloc] initWithString:#"Your text" attributes:attrsDictionary];

NSGradient into NSColor

OK, long story short:
I'm using (embedded into the bundle) FontAwesome
I'm using it as the font in some custom NSButtons
In the NSButton subclass I want to colour them, exactly the way the Xcode tab items are coloured
This is how I'm setting the color (as a simple NSColor):
NSColor *color = [NSColor colorWithCalibratedRed:0.09 green:0.55 blue:0.90 alpha:1.0];
NSMutableAttributedString *colorTitle =
[[NSMutableAttributedString alloc] initWithAttributedString:[self attributedTitle]];
NSRange titleRange = NSMakeRange(0, [colorTitle length]);
[colorTitle addAttribute:NSForegroundColorAttributeName
value:color
range:titleRange];
[self setAttributedTitle:colorTitle];
How can I set it to an NSGradient?
OK, here's the solution, for anyone who may find useful...
Step 1:
Create a category on NSColor, based on the great answer by #Omz. In the code below, you'll see it renamed as colorFromGradient:, solely in order to mix well with the usual Cocoa naming conventions...
Step 2:
Redraw the title with the gradient color
NSColor* gS = [NSColor colorWithCalibratedRed:0.07 green:0.47 blue:0.87 alpha:1.0];
NSColor* gE = [NSColor colorWithCalibratedRed:0.12 green:0.64 blue:0.94 alpha:1.0];
NSGradient* g = [[NSGradient alloc] initWithStartingColor:gE endingColor:gS];
NSColor *color = [NSColor colorFromGradient:g];
NSMutableAttributedString *colorTitle =
[[NSMutableAttributedString alloc] initWithAttributedString:[self attributedTitle]];
NSRange titleRange = NSMakeRange(0, [colorTitle length]);
[colorTitle addAttribute:NSForegroundColorAttributeName
value:color
range:titleRange];
[self setAttributedTitle:colorTitle];
Step 3:
Enjoy the result. :-)

UItextfield adding extra spaces beneath timestamp

I have a relatively simple comment box (UITextfield) for a photo app into which I've found that when entering long comments (usually more than half a dozen words) a lot of blank space appears below the timestamp ("X minutes ago") within the comment box. The longer the post, the more blank space appears within the box. Everything else works fine, the comment is vertically aligned correctly, and the timestamp is directly below this.
self.backgroundColor = [UIColor clearColor];
mainView = [[UIView alloc] initWithFrame:CGRectMake( 20.0f, 0.0f, 280.0f, 51.0f)];
mainView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"BackgroundComments.png"]];
[self addSubview:mainView];
UIImageView *messageIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"IconAddComment.png"]];
messageIcon.frame = CGRectMake( 9.0f, 17.0f, 19.0f, 17.0f);
[mainView addSubview:messageIcon];
UIImageView *commentBox = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:#"TextFieldComment.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(5.0f, 10.0f, 5.0f, 10.0f)]];
commentBox.frame = CGRectMake(35.0f, 8.0f, 237.0f, 35.0f);
[mainView addSubview:commentBox];
commentField = [[UITextField alloc] initWithFrame:CGRectMake( 40.0f, 10.0f, 227.0f, 31.0f)];
commentField.font = [UIFont systemFontOfSize:14.0f];
commentField.placeholder = #"Add a comment";
commentField.returnKeyType = UIReturnKeySend;
commentField.textColor = [UIColor colorWithRed:73.0f/255.0f green:55.0f/255.0f blue:35.0f/255.0f alpha:1.0f];
commentField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
[commentField setValue:[UIColor colorWithRed:154.0f/255.0f green:146.0f/255.0f blue:138.0f/255.0f alpha:1.0f] forKeyPath:#"_placeholderLabel.textColor"];
[mainView addSubview:commentField];
Any help would be much appreciated!

Adding text to a UIScrollView

I'm creating a tape measure in a UIScrollView, it has horizontal lines from an image and I want to add the numbers programatically.
(Note the blue was to help getting the layout right)
I tried this:
for (NSInteger i = 0; i < self.maxUnits.integerValue; i++) {
static CGFloat labelWidth = 40;
CGFloat x = (halfScreen - (labelWidth/2)) + (i * self.widthOfOneFraction.floatValue * self.numberOfFractions.floatValue);
CGRect frame = CGRectMake(x-1, 41, labelWidth, 70);
UILabel *label = [[UILabel alloc] initWithFrame:frame];
label.text = [NSString stringWithFormat:#"%d", i];
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor tlbBlueColor];
label.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:20.0];
[self addSubview:label];
}
Which works, but uses about 40Mb of RAM. I thought that adding the text in a CATextLayer might be more efficient, but I can't get it working:
for (NSInteger i = 0; i < self.maxUnits.integerValue; i++) {
CATextLayer *label = [[CATextLayer alloc] init];
[label setFont:#"HelveticaNeue-Light"];
[label setFontSize:20];
[label setFrame:frame];
[label setString:[NSString stringWithFormat:#"%d", i]];
[label setAlignmentMode:kCAAlignmentCenter];
[label setForegroundColor:[[UIColor whiteColor] CGColor]];
[self.layer addSublayer:label];
}
The numbers don't appear on the screen.
So my question is can I either make the first way more efficient, and if not is the second way more efficient when it works and if so how do I get it working?
I changed the way the loading worked so as to only load items on display and to load a few more as you scroll.
This seems to have totally fixed the high memory issue and even if you scroll to both ends it doesn't use the same high amount of memory. I guess there was a leak in how my original code worked.

Glow effect in UITextView

Can glow effects be applied on text inside UITextView? If so, how?
Here is some code to add a red glow to a UITextView. Requires iOS 6+. Adjust parameters to taste:
NSShadow *shadow = [NSShadow new];
shadow.shadowBlurRadius = 5;
shadow.shadowColor = [UIColor redColor];
shadow.shadowOffset = CGSizeMake(0, 0);
NSDictionary *attributes = #{NSShadowAttributeName:shadow};
textView.attributedText = [[NSAttributedString alloc]
initWithString:title
attributes:attributes];
Not really. You might be able to use a CSS-styled (using the text-shadow property) <textarea> in a UIWebView, though.