Glow effect in UITextView - objective-c

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.

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];

How do I make UITextView's tappable links NOT have an underline?

I'm setting up a UITextView, and it has links that you can tap that will open in Safari.
UITextView *tv = [[UITextView alloc] initWithFrame:CGRectMake(35, 100, 300, 400)];
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:[#"<a href='http://google.ca'>test</a>" dataUsingEncoding:NSUTF8StringEncoding] options:#{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: #(NSUTF8StringEncoding)} documentAttributes:nil error:nil];
tv.attributedText = attributedString;
[self.view addSubview:tv];
It basically takes an HTML string in (with an <a href=... in it) and then using the HTML parsing methods in iOS 7 gives me my tappable UITextView links.
However, if I add the following line before I add the text view to my view:
tv.linkTextAttributes = #{
NSUnderlineStyleAttributeName: #(NSUnderlineStyleNone)
};
Nothing changes. I can set it to be NSUnderlineStyleThick and it gets thicker. I can change the NSForegroundColorAttributeName to [UIColor redColor] to make the text red, but I cannot figure out how to get the text to not have an underline.
What am I doing wrong?
You can use [NSMutableAttributedString alloc] initWithString:str instead of NSAttributedString alloc] initWithData:data. Links will automatic detected and not underline
Try to use code below:
NSString *str = #"http://google.ca";
NSAttributedString * attributedString = [[NSMutableAttributedString alloc] initWithString:str];
tv.attributedText = attributedString;

New NSAttributedString multiline

I worked UILabel. But setLineBreakMode is deprecated.
I have been using NSAttributedString.
but UILabel setLineBreakMode is
After that UILabel setNumberOfLines else does not work.
Before:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(42.0f, 10.0f, 275.0f, 50.0f)];
label.text = #"XXXXXX";
memoLabel.textAlignment = UITextAlignmentLeft;
memoLabel.numberOfLines = 2;
memoLabel.lineBreakMode = UILineBreakModeTailTruncation;
memoLabel.font = [UIFont systemFontOfSize:11];
memoLabel.backgroundColor = [UIColor clearColor];
IOS 6 after:
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft;
NSAttributedString *string
= [[NSAttributedString alloc] initWithString:text
attributes:[NSDictionary
dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:11],
NSFontAttributeName,
paragraphStyle, NSParagraphStyleAttributeName,nil]];
[paragraphStyle release];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(42.0f, 10.0f, 275.0f, 50.0f)];
label.attributedText = string;
[string relase];
I want to be the same before and after the display.
How to display multiple lines?
The lineBreakMode property isn't deprecated in iOS 6. It has simply changed the names of the constants. The old constants are deprecated, but still available. You can use the new constants even if you are deploying to an older iOS, because the constants are just enum values. The old names and the new names have the same values. So, just set memoLabel.lineBreakMode = NSLineBreakByTruncatingTail.
Your example code doesn't appear to take advantage of any attributed string specific features. If you don't need an attributed string, just keep using a plain string. That still works in iOS 6.
Use NSLineBreakByTruncatingTail instead of UILineBreakModeTailTruncation

How to add text shadows to a UITextView?

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;

A More Concise Way to do This in Objective C?

So I have something like this in my code:
leftMostLabel = [[UILabel alloc] initWithFrame:CGRectMake(60.0f, 2.0f, 80.0f, 40.0f)];
leftMostLabel.text = #"Some text";
leftMostLabel.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
leftMostLabel.backgroundColor = [UIColor clearColor];
leftMostLabel.textAlignment = UITextAlignmentCenter;
leftMostLabel.font = [UIFont boldSystemFontOfSize:13.0];
leftMostLabel.userInteractionEnabled = NO;
centerLeftLabel = [[UILabel alloc] initWithFrame:CGRectMake(115.0f, 2.0f, 80.0f, 40.0f)];
centerLeftLabel.text = currentDate;
centerLeftLabel.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
centerLeftLabel.backgroundColor = [UIColor clearColor];
centerLeftLabel.textAlignment = UITextAlignmentCenter;
centerLeftLabel.font = [UIFont systemFontOfSize:12.0];
centerLeftLabel.userInteractionEnabled = NO;
Which is working fine and dandy, but I repeat that format many many times. I would ideally like to pass in the variable(leftMostLabel, centerLeftLabel, etc.) to a function which creates the labels for me behind the scenes based on the name of the variable that I pass to it, as well as whichever additional parameters I feed it. This possible? If so, how would I go about this?
Thanks in advance!
Objective-C offers the possibility to extend existing classes via categories, so you could easily add a method to UILabel such as: +labelWithFrame:text:textColor:backgroundColor:alignment:font:interaction:. That'd shorten things a bit, so your code would look like:
UILabel *leftLabel = [UILabel labelWithFrame:CGRectMake(...)
text:#"Yoo hoo!"
textColor:[UIColor blueColor]
backgroundColor:[UIColor clearColor]
textAlignment:UITextAlignmentLeft
font:[UIFont systemFontOfSize:12];
userInteractionEnabled:NO];
That's somewhat less cluttered looking and might be worthwhile.
If most of your labels are similar, another option would be to add a method that creates a label using a prototype. UIView's don't implement NSCopying, so you can't just make a copy of a label using the -copy method, but you can write a method that creates a new label and configures it based on an existing label. Calling it might look like:
UILabel *centerLabel = [UILabel labelWithFrame:CGRectMake(...)
likeLabel:leftLabel];
centerLabel.text = #"Hey there!";
Finally, consider using Interface Builder to create all these labels. Cocoa and Cocoa Touch code would be chock full of calls to view configuration methods like -initWithFrame: and -addSubview: if it weren't for IB. It may or may not be appropriate in your case, but sometimes people avoid IB because they think it's more work or makes their code more difficult to manage; I think the opposite is true.
Concise, there's a word you don't see too often in conjunction with Objective-C. Coming from another language I feel your pain with snippets like these.
I've resorted to writing the necessary label variations once, and then repeat them many times over. The other posted answers are all viable options, though I'm not so sure about the concise argument. #Caleb's 'likeLabel' answer is the most versatile, but you still need to be able to reference that other label.
I make a project-specific category on UILabel, and place the various labels in there my self. The only thing I'm comfortable repeating for every label is the frame and the text. There's not really a neccessity to put +methods in a category, but UILabel does sum up what you want quite nicely. After having the categories in place, this is how you'd use it:
UILabel *someLabel = [UILabel headerLabelWithFrame:CGRectMake(10, 10, 256, 32) andText:#"Conciseness"];
And this is what the category would look like with just one label type. You'd add more if needed:
#interface UILabel (ProjectSpecificLabels)
+(UILabel *)headerLabelWithFrame:(CGRect)frame andText:(NSString *)text;
#end
#implementation UILabel (ProjectSpecificLabels)
+(UILabel *)headerLabelWithFrame:(CGRect)frame andText:(NSString *)text {
UILabel *label = [[[self alloc] initWithFrame:frame] autorelease];
label.text = text;
label.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [UIFont boldSystemFontOfSize:13.0];
label.userInteractionEnabled = NO;
return label;
}
#end
Hope it helps.
Cheers,
EP.
I would break it up into a function that sets my values.
leftMostLabel = [[UILabel alloc] initWithFrame:CGRectMake(60.0f, 2.0f, 80.0f, 40.0f)];
leftMostLabel.text = #"Some text";
[self initLabelValues:leftMostLabel withFont:[UIFont boldSystemFontOfSize:13.0]];
centerLeftLabel = [[UILabel alloc] initWithFrame:CGRectMake(115.0f, 2.0f, 80.0f, 40.0f)];
centerLeftLabel.text = currentDate;
[self initLabelValues:centerLeftLabel withFont:[UIFont boldSystemFontOfSize:12.0]];
-(void) initLabelValues:(UILabel*)inLabel withFont:(UIFont*)font {
[inLabel setTextColor:[UIColor colorWithWhite:1.0 alpha:1.0]];
[inLabel setBackgroundColor:[UIColor clearColor]];
[inLabel setTextAlignment:UITextAlignmentCenter];
[inLabel setUserInteractionEnabled:NO];
[inLabel setFont:font];
}