The advantage os this implementation is that it uses the ability of UILabel to display NSAttributedString on iOS 6.0+. There is no hacking of the drawRect: or drawText: method of UILabel. CoreText is used only to detect touched letters.
- Draws text exactly the same way as UILabel
- Dead simple implementation, look at the source code.
PPLabel requires iOS 6+
CocoaPods is the recommended way to add PPLabel to your project.
- Add a pod entry for PPLabel to your Podfile pod 'PPLabel', '~> 0.5'
- Install the pod(s) by running pod install.
- Include PPLabel wherever you need it with #import <PPLabel.h>.
- Obtain the last version of PPLabel from the master branch.
- Add PPLabel.h and PPLabel.m into your project
- Import CoreText framework into your project.
- Have a look at the example project and enjoy PPLabel.
The example project highlights touched words in a label. This behaviour can be modified to highlight touched links, hashtags or whatever you want.
//
// ViewController.h
// PPLabel
//
// Created by Petr Pavlik on 12/28/12.
// Copyright (c) 2012 Petr Pavlik. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "PPLabel.h"
@interface ViewController : UIViewController <PPLabelDelegate>
@property (weak, nonatomic) IBOutlet PPLabel *label;
@end
//
// ViewController.m
// PPLabel
//
// Created by Petr Pavlik on 12/28/12.
// Copyright (c) 2012 Petr Pavlik. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic) NSRange highlightedRange;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.label.delegate = self;
}
#pragma mark PPLabelDelegate
- (BOOL)label:(PPLabel *)label didBeginTouch:(UITouch *)touch onCharacterAtIndex:(CFIndex)charIndex {
[self highlightWordContainingCharacterAtIndex:charIndex];
return NO;
}
- (BOOL)label:(PPLabel *)label didMoveTouch:(UITouch *)touch onCharacterAtIndex:(CFIndex)charIndex {
[self highlightWordContainingCharacterAtIndex:charIndex];
return NO;
}
- (BOOL)label:(PPLabel *)label didEndTouch:(UITouch *)touch onCharacterAtIndex:(CFIndex)charIndex {
[self removeHighlight];
return NO;
}
- (BOOL)label:(PPLabel *)label didCancelTouch:(UITouch *)touch {
[self removeHighlight];
return NO;
}
#pragma mark --
- (void)highlightWordContainingCharacterAtIndex:(CFIndex)charIndex {
if (charIndex==NSNotFound) {
//user did nat click on any word
[self removeHighlight];
return;
}
NSString* string = self.label.text;
//compute the positions of space characters next to the charIndex
NSRange end = [string rangeOfString:@" " options:0 range:NSMakeRange(charIndex, string.length - charIndex)];
NSRange front = [string rangeOfString:@" " options:NSBackwardsSearch range:NSMakeRange(0, charIndex)];
if (front.location == NSNotFound) {
front.location = 0; //first word was selected
}
if (end.location == NSNotFound) {
end.location = string.length-1; //last word was selected
}
NSRange wordRange = NSMakeRange(front.location, end.location-front.location);
if (front.location!=0) { //fix trimming
wordRange.location += 1;
wordRange.length -= 1;
}
if (wordRange.location == self.highlightedRange.location) {
return; //this word is already highlighted
}
else {
[self removeHighlight]; //remove highlight on previously selected word
}
self.highlightedRange = wordRange;
//highlight selected word
NSMutableAttributedString* attributedString = [self.label.attributedText mutableCopy];
[attributedString addAttribute:NSBackgroundColorAttributeName value:[UIColor redColor] range:wordRange];
self.label.attributedText = attributedString;
}
- (void)removeHighlight {
if (self.highlightedRange.location != NSNotFound) {
//remove highlight from previously selected word
NSMutableAttributedString* attributedString = [self.label.attributedText mutableCopy];
[attributedString removeAttribute:NSBackgroundColorAttributeName range:self.highlightedRange];
self.label.attributedText = attributedString;
self.highlightedRange = NSMakeRange(NSNotFound, 0);
}
}
@end
Many thanks to Mattt Thomson and his TTTAttributedLabel. It was a big inspiration.
petrpavlik on App.net
PPLabel is available under the MIT license.