UILabel with Multiple links - ios

Hello I am trying to tappable UILabel similar to Facebook's like text, Label's text would be similar to
"You, Steve and 50 others like this."
Where "You", "Steve" and "50 others" should be tappable separately.
I am trying my luck with NSAttributedString but it is not helping me, Can anyone help me to find a way ?

try this, but it's not for label but it's for textView.
NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:#"firstsecond"];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,5)];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(5,6)];
//[string addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:10] range:NSMakeRange(0,5)];
[string addAttribute:NSLinkAttributeName value:[NSURL URLWithString:#"http://www.google.co.in"] range:NSMakeRange(0,5)];
[string addAttribute:NSLinkAttributeName value:[NSURL URLWithString:#"http://www.yahoo.com"] range:NSMakeRange(5,6)];
self.txtView.attributedText=string;
self.txtView.scrollEnabled = NO;
self.txtView.editable = NO;
self.txtView.textContainer.lineFragmentPadding = 0;
self.txtView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
self.txtView.delegate = self;
}
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)url inRange: (NSRange)characterRange
{
return YES;
}

Related

more and less button with textview or label

hi i want a textview or label with see more and less functionality. i tried with label and successfully got result as:
but if text will increase it button more will look like :
and in some conditions it will look :
i am trying to set button will automatically set according to text.can anyone suggest me better way to got this.
If you are using UILabel than you can use TTTAttributedLabel in that you can set clickable text.
Append your string "see more" or "less functionality" with label text and make it clickable.
So there is my simple code that create label with TTTAttributedLabel to implement 'more...' and 'less...' functionality for label:
- (void) setupStoreTitleLabel {
self.titleLabel.delegate = self;
[self.titleLabel setText:self.card.name];
self.titleLabel.numberOfLines = 2;
NSAttributedString *showMore = [[NSAttributedString alloc] initWithString:#" more..." attributes:#{
NSForegroundColorAttributeName:[UIColor blueColor],
NSFontAttributeName : [UIFont boldSystemFontOfSize:12],
NSLinkAttributeName : [NSURL URLWithString:#"more..."]
}];
[self.titleLabel setAttributedTruncationToken:showMore];
}
#pragma mark - TTTAttributedLabelDelegate
- (void)attributedLabel:(__unused TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url
{
NSLog(#"%# pressed", url);
if ([[url absoluteString] isEqualToString:#"more..."]) {
self.titleLabel.numberOfLines = 99;
NSString *cardNameWithLess = [NSString stringWithFormat:#"%# %#",self.card.name, #" less..."];
[self.titleLabel setText:cardNameWithLess afterInheritingLabelAttributesAndConfiguringWithBlock:^NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
//code
NSRange linkRange = [[mutableAttributedString string] rangeOfString:#" less..." options:NSCaseInsensitiveSearch];
[mutableAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:linkRange];
[mutableAttributedString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:12] range:linkRange];
[mutableAttributedString addAttribute:NSLinkAttributeName value:[NSURL URLWithString:#"less..."] range:linkRange];
return mutableAttributedString;
}];
} else {
self.titleLabel.numberOfLines = 2;
NSAttributedString *showMore = [[NSAttributedString alloc] initWithString:#" more..." attributes:#{
NSForegroundColorAttributeName:[UIColor blueColor],
NSFontAttributeName : [UIFont boldSystemFontOfSize:12],
NSLinkAttributeName : [NSURL URLWithString:#"more..."]
}];
[self.titleLabel setAttributedTruncationToken:showMore];
[self.titleLabel setText:self.card.name];
}
}

How to bold some words in my UITextView using NSMutableAttributedString?

I have a UITextView and there are certain words I'm casting with NSString stringWithFormat that I'd like to be bolded.
I have looked around Stack Overflow and tried to follow the the postings but I guess I'm not understanding it.
Here's what I've been playing around with:
NSRange boldedRange = NSMakeRange(0, 4);
NSString *boldFontName = [[UIFont fontWithName:#"Helvetica-Bold" size:100]fontName];
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:self.name];
[attrString beginEditing];
[attrString addAttribute:NSFontAttributeName
value:boldFontName
range:boldedRange];
[attrString endEditing];
self.resultsTextView.attributedText = attrString;
self.resultsTextView.text = [NSString stringWithFormat:#"One day, %# was taking a walk and saw a %# boy. He was %# a %#.", attrString, self.adjective, self.adverb, self.noun];
You can also set it the following way if you want by setting a dictionary as a whole, as attribute
NSString *strTextView = #"This is some demo Text to set BOLD";
NSRange rangeBold = [strTextView rangeOfString:#"BOLD"];
UIFont *fontText = [UIFont boldSystemFontOfSize:10];
NSDictionary *dictBoldText = [NSDictionary dictionaryWithObjectsAndKeys:fontText, NSFontAttributeName, nil];
NSMutableAttributedString *mutAttrTextViewString = [[NSMutableAttributedString alloc] initWithString:strTextView];
[mutAttrTextViewString setAttributes:dictBoldText range:rangeBold];
[textViewTermsPolicy setAttributedText:mutAttrTextViewString];
Use the below code to set Attribute string in TextView.
NSString *infoString =#"I am Kirit Modi from Deesa.";
NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:infoString];
UIFont *font_regular=[UIFont fontWithName:#"Helvetica" size:20.0f];
UIFont *font_bold=[UIFont fontWithName:#"Helvetica-Bold" size:20.0f];
[attString addAttribute:NSFontAttributeName value:font_regular range:NSMakeRange(0, 4)];
[attString addAttribute:NSFontAttributeName value:font_bold range:NSMakeRange(5, 15)];
[attString addAttribute:NSFontAttributeName value:font_regular range:NSMakeRange(16, infoString.length - 15 - 1)];
[self.txtView setAttributedText:attString];
OutPut :
Check out #CrazyYoghurt improvement on #Bbrame and #BenoitJadinon on this previous SO question 3586871
I've been using it for over a year and it works great. One limitation: I don't think you can bold multiple times the same string if it appears more than once in your original string. But you can probably expend the code to make it do so if you wish.
If you also need to filter some word from the UITextView and make it underline/change color of that particular text only then you can use the below code.
Here, I'm getting all the doc text in the Content string and filter some particular text that is in Hebrew language.
NSMutableAttributedString *aStr = [[NSMutableAttributedString alloc]initWithString:content attributes:nil];
[aStr addAttribute:NSLinkAttributeName value:#"http://www.apple.com" range:[content rangeOfString:#"מדיניות פרטיות"]];
[aStr addAttribute:NSLinkAttributeName value:#"http://www.google.com" range:[content rangeOfString:#"לינק"]];
textview.linkTextAttributes = #{NSUnderlineStyleAttributeName : #(NSUnderlineStyleSingle)};
textview.delegate = (id)self;
//...You can as per your custom color
[aStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:[content rangeOfString:#"מדיניות פרטיות"]];
[aStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:[content rangeOfString:#"לינק"]];
//Here You can also add the tap gesture on that text.
//Tap gesture
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tappedTextView:)];
[textview addGestureRecognizer:tapRecognizer];
[textview setAttributedText:aStr];
textview.textAlignment=NSTextAlignmentRight;
//For getting the text location in the tap gesture
-(void)tappedTextView:(UITapGestureRecognizer *)tapGesture
{
UITextView *textView = (UITextView *)tapGesture.view;
CGPoint tapLocation = [tapGesture locationInView:textView];
UITextPosition *textPosition = [textView closestPositionToPoint:tapLocation];
NSDictionary *attributes = [textView textStylingAtPosition:textPosition inDirection:UITextStorageDirectionForward];
NSString *urlStr = attributes[NSLinkAttributeName];
if (urlStr)
{
//[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",url]]];
PrivacyViewController *next = [PrivacyViewController new];
[self.navigationController pushViewController:next animated:YES];
}
}

Comparing 2 of the same NSAttributedStrings not working

Why does comparing the same NSAttributedString not work?
I have the following:
- (void)someSetupClass {
NSMutableAttributedString *aString = [[NSMutableAttributedString alloc] initWithString:#"abcdefghijklmnopqrstuvwxyz"];
[aString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,5)];
[aString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Light" size:(16.0)] range:NSMakeRange(0, 20)];
[aString addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(5,6)];
_aTextView.attributedText = aString;
_aTextView.delegate = self;
[_scroll addSubview:_best];
}
- (void)textViewDidBeginEditing:(UITextView *)textView {
NSMutableAttributedString *aString = [[NSMutableAttributedString alloc] initWithString:#"abcdefghijklmnopqrstuvwxyz"];
[aString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,5)];
[aString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Light" size:(16.0)] range:NSMakeRange(0, 20)];
[aString addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(5,6)];
if ([textView.attributedText isEqualToAttributedString:aString]) {
// Never reaches here, but why?
textView.text = #"";
// textView.textColor = [UIColor blackColor];
}
[textView becomeFirstResponder];
}
Make that textview strongly typed variable and try. Eg.
#property(nonatomic, strong)UITextView * aTextView;
Check if your textView has default font set to Helvetica/system - size 12. May be because of this last part of your attributed string is taking default font of the textView after you setText. But part of aString (uvwxyz) does not have font assigned and hence it mismatches.
Hope this helps you :)

UILabel: Custom underline color?

I need the text of a UILabel to be black, but have a light gray underline under the text. Is this possible with NSAttributedString or TTTAttributedLabel? Or is custom drawing using Core Graphics needed?
CLARIFICATION:
I need a specific color text on a different color underline. Example: blue text on red underline.
You can do with NSAttributedString as below.
NSMutableAttributedString* string = [[NSMutableAttributedString alloc]initWithString:#"you string"];
[string addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, string.length)];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, string.length)];//TextColor
[string addAttribute:NSUnderlineStyleAttributeName value:underlineNumber range:NSMakeRange(0, string.length)];//Underline color
[string addAttribute:NSUnderlineColorAttributeName value:[UIColor lightGrayColor] range:NSMakeRange(0, string.length)];//TextColor
yourlabel. attributedText = string;
Note: You can also underline particular range of string as like in this post. Also note down, it works ios6+ only.
Instead of creating a local NSMutableAttributedString and adding attributes one by one, we can always create multiple attributes in one single line (using NSDictionary symbols - # { } ) to a specific UILabel including the actual text.
Objective C:
[someUILabel setAttributedText:
[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:#"%#", [someObject stringProperty]]
attributes:#{NSUnderlineStyleAttributeName:#(NSUnderlineStyleThick),
NSUnderlineColorAttributeName:[[UIColor alloc] initWithRed:0.953f green:0.424f blue:0.416f alpha:1.00f]}]];
In the above example we have set an underline which is also bold - total 2 attributes.
Swift:
self.someUIButton.setAttributedTitle(NSAttributedString(string: "UIButtonStringTitle", attributes: [NSUnderlineStyleAttributeName : 1]), forState: .Normal)
// Print `str` in black, and underline the word STRING in gray.
NSMutableAttributedString *str = [[NSMutableAttributedString alloc]initWithString:#"This is my STRING"];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, str.length-7)];
[str addAttribute:NSUnderlineColorAttributeName value:[UIColor grayColor] range:NSMakeRange([str length]-6, 6)];
[str addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:NSUnderlineStyleSingle] range:NSMakeRange([str length]-6, 6)];
_label.attributedText = str; // assuming you have an iVar name `label`
NSAttributedString *title;
title = [[NSAttributedString alloc] initWithString:#"iphone app" for NSAttributedString" attributes:#{ NSFontAttributeName : [UIFont fontWithName:#"Noteworthy-Bold" size:36], NSUnderlineStyleAttributeName : #1 , NSStrokeColorAttributeName : [UIColor blackColor]}];
UILabel *label;
label = [[UILabel alloc] initWithFrame:CGRectMake( (self.view.bounds.size.width - title.size.width) / 2.0f, 40.0f, title.size.width, title.size.height)];
label.attributedText = title;
[self.view addSubview:label];
m-farhan.com farhan will be underlined
//-----------------------------
// Create attributed string
//-----------------------------
NSString *str = #"m-Farhan.com";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
// Add attribute NSUnderlineStyleAttributeName
[attributedString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:NSUnderlineStyleSingle] range:NSMakeRange(2, 4)];
// Set background color for entire range
[attributedString addAttribute:NSBackgroundColorAttributeName
value:[UIColor colorWithRed:0.103 green:0.305 blue:0.492 alpha:1.000]
range:NSMakeRange(0, [attributedString length])];
// Define label
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 280, 80)];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setTextColor:[UIColor whiteColor]];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextAlignment:UITextAlignmentLeft];
// Set label text to attributed string
[label setAttributedText:attributedString];
[[self view] addSubview:label];
In swift, use NSAttributedString.Key.underlineColor.

UIRefreshControl attributedTitle multiple lines

Is it possible to use multiple lines in the UIRefreshControl title? Whenever I add \n to the NSAttributedString only the first line will be displayed. I'm trying to set a title and on the next line some more text. So is there a workaround to use two lines of text in the UIRefreshControl?
This is the current code where only "Title Here" is displayed:
self.refreshControl = [[UIRefreshControl alloc] init];
NSString *title = #"Title Here";
NSString *subText = #"Subtext Here";
NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"%#\n%#",title,subText]];
[attString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Helvetica" size:20.0f] range:NSMakeRange(0, [title length])];
[attString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Helvetica" size:14.0f] range:NSMakeRange([title length],[subText length])];
[attString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, [title length])];
[attString addAttribute:NSForegroundColorAttributeName value:[UIColor lightGrayColor] range:NSMakeRange([title length], [subText length])];
self.refreshControl.attributedTitle = attString;
here is a tricky method: find the UILabel in the UIRefreshControl and set numberOfLines = 0.
UILabel *titleLabel = [[[[self.refreshControl subviews] firstObject] subviews] lastObject];
if (titleLabel) {
titleLabel.numberOfLines = 0;
NSString title = #"Pull to Refresh.\nUpdated Time: 09:30"; // \n for new line.
self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:title];
}
This piece of code will work
NSString *title = #"Title Here";
NSString *subText = #"Subtext Here";
NSMutableAttributedString *titleAttString = [[NSMutableAttributedString alloc] initWithString:title];
NSMutableAttributedString *subTitleAttString = [[NSMutableAttributedString alloc] initWithString:subText];
[titleAttString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Helvetica" size:20.0f] range:NSMakeRange(0, [title length])];
[subTitleAttString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Helvetica" size:14.0f] range:NSMakeRange(0,[subTitle length])];
[titleAttString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, [title length])];
[subTitleAttString addAttribute:NSForegroundColorAttributeName value:[UIColor lightGrayColor] range:NSMakeRange(0, [subTitle length])];
[titleAttString appendAttributedString:subTitleAttString];
self.refreshControl.attributedTitle = titleAttString;
The trick is to change the UILable's property of Refresh Controller to Zero.
The hack is we have to find the label through the subviews and there child as shown below.
Here is a Swift version
if let refreshLabel = refreshControl?.subviews.first?.subviews.last as? UILabel {
refreshLabel.numberOfLines = 0
}
So here is the full code sample
private var marketRefreshController = UIRefreshControl()
private var lastUpdatedDate = Date()
override func viewDidLoad() {
super.viewDidLoad()
tableView.refreshControl = marketRefreshController
if let refreshLabel = refreshControl?.subviews.first?.subviews.last as? UILabel {
refreshLabel.numberOfLines = 0
}
marketRefreshController.addTarget(self, action: #selector(refreshMarketData), for: .valueChanged)
marketRefreshController.tintColor = UIColor.blue
let textAttributes = [NSAttributedString.Key.font: UIFont.appSubTitle,
NSAttributedString.Key.foregroundColor: UIColor.blue]
let timeSinceLastUpdate = lastUpdatedDate.timeAgoSinceNow // Date Sting Converter Helper Method
let displayString = "Fetching Market Data ... \n Last Updated: \(timeSinceLastUpdate)"
marketRefreshController.attributedTitle = NSAttributedString(string: displayString,
attributes: textAttributes)
tableView.addSubview(marketRefreshController)
}
The expected output should be like -

Resources