Similar to iPhone
mail, I want to display recipients as UIButton
. But I am not able to implement it correctly.
I am creating all recipients over a single UILabel and then assigning attributed text to it.
NSMutableArray *arrRecipients = [NSMutableArray new];
if([message.Recipients containsString:@", "])
{
NSArray *arr = [message.Recipients componentsSeparatedByString:@", "];
for(int i = 0; i < arr.count; i++)
{
[arrRecipients addObject:[arr objectAtIndex:i]];
}
}
else
{
[arrRecipients addObject:message.Recipients];
}
NSString *recipientString = @"";
for(int i = 0; i < arrRecipients.count; i++)
{
if([recipientString isEqual:@""])
recipientString = [arrRecipients objectAtIndex:i];
else
recipientString = [recipientString stringByAppendingString:[NSString stringWithFormat:@" %@", [arrRecipients objectAtIndex:i]]];
}
NSMutableAttributedString *str = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"%@: %@", NSLocalizedString(@"to", nil), recipientString]];
for(NSString *value in arrRecipients)
{
NSRange range = [recipientString rangeOfString:value];
[str addAttribute:NSBackgroundColorAttributeName value:[UIColor colorWithRed:205.0/255.0 green:205.0/255.0 blue:205.0/255.0 alpha:1.0] range:NSMakeRange(range.location + 4, range.length)];
}
UILabel *recipients = [[UILabel alloc]initWithFrame:CGRectMake(5, subject.frame.origin.y + subject.frame.size.height + 6, viewHeader.frame.size.width - 5, 20)];
recipients.attributedText = str;
recipients.numberOfLines = 0;
recipients.font = [UIFont systemFontOfSize:14];
[viewHeader addSubview:recipients];
[recipients sizeToFit];
[viewHeader sizeToFit];
Results :
Not a quite good one.
How can I improve it ?
You should use UITextView
with attributed string key NSLinkAttributeName
and handle tap on each name with its respective UITextView
delegate.
NSMutableAttributedString *str = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"%@: %@", NSLocalizedString(@"to", nil), recipientString]];
for(NSString *value in arrRecipients)
{
NSRange range = [recipientString rangeOfString:value];
[str addAttribute:NSBackgroundColorAttributeName value:[UIColor colorWithRed:205.0/255.0 green:205.0/255.0 blue:205.0/255.0 alpha:1.0] range:NSMakeRange(range.location + 4, range.length)];
[str addAttribute: NSLinkAttributeName value:"a custom url scheme" range:NSMakeRange(range.location + 4, range.length)];
}
Then handle in this method:
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
if ([[URL scheme] isEqualToString:@"myurl"]) {
// Handle tap
return NO;
}
return YES;
}
Like in mail or in other apps we can have a functionality of tags which can differentiate between list of items. Below links may help you out: https://www.cocoacontrols.com/search?q=tags https://www.cocoacontrols.com/controls/aktagsinputview
Like what @Mohamad Sheikh suggested, you could use a UITextView with attributed string or actually subclass it to create your own is easier to manage in my opinion.
If you don't mind using external library, in one of my project i uses this pod
CLTokenInputView. Is really easy to use and save me hours of implementing my own. The swift version is here.
Then just follow the protocol in the CLTokenInputViewDelegate
and implement your code in the following:
func tokenInputView(aView:CLTokenInputView, didAddToken token:CLToken)
func tokenInputView(aView:CLTokenInputView, didRemoveToken token:CLToken)
You can use this one. Have you seen https://github.com/venmo/VENTokenField ?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With