UIView subclass that renders tweet text (parsing links, hashtags & user mentions) according to Twitter's display guidelines at https://dev.twitter.com/terms/display-guidelines (well, it gets you most of the way there, anyway).
Objective-C
Switch branches/tags
Nothing to show
Clone or download
Pull request Compare This branch is 6 commits ahead, 7 commits behind markbeaton:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
NSString+Enhancements.h
NSString+Enhancements.m
README.markdown
WMARecognizer.h
WMARecognizer.m
WMATweetView.h
WMATweetView.m
example.png

README.markdown

WMATweetView

This is a self-contained UIView subclass that renders the text portion of a tweet according to Twitter's guidelines at https://dev.twitter.com/terms/display-guidelines.

It parses the following tweet entities & provides callbacks for tap gestures:

  • URLs
  • #Hashtags
  • User @mentions
  • Media links

The callbacks are passed an instance of a WMATweetEntity subclass that contains all of the data you'll need to process the tap according to Twitter's guidelines.

Encoded ampersands (&) are also replaced with a plain "&" character.

Note: this view only renders the tweet text - you're responsible for adding avatars, author names, dates etc. But that's the easy part! Example:

Supported iOS versions/ARC support

The code should work on iOS 4.0 and above. It might even work on iOS 3.2 (when CoreText was made public), although I haven't tested that at all.

It also supports including in both ARC and non-ARC Xcode projects - you don't have to set any flags, it's all handled via compile-time macros (thanks to John Blanco).

Example usage

Once you've added the WMATweetView.h & WMATweetView.m files to your Xcode project, you'll need to add a reference to CoreText.framework as well.

Currently, there are two ways to initialise the view:

From an NSDictionary

This is the easiest option - assuming you've got an NSDictionary instance containing the tweet data (i.e. from Twitter's API), you can just pass that to the view's initWithTweet: initialiser.

Contrived example:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
	// Set up window
	self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	self.window.backgroundColor = [UIColor whiteColor];
	
	// Get tweet dictionary from JSON - typically, this would come from Twitter's API rather than a resource file...
	NSData *tweetData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tweet" ofType:@"json"]];
	NSDictionary *tweet = [NSJSONSerialization JSONObjectWithData:tweetData options:0 error:NULL];
	
	// Build & add tweet view - let's emulate Tweetbot
	WMATweetView *tweetView = [[WMATweetView alloc] initWithTweet:tweet frame:CGRectMake(10, 30, 300, 300)];
	
	tweetView.backgroundColor = [UIColor colorWithRed:0.906 green:0.945 blue:0.980 alpha:1.];
	tweetView.textColor = [UIColor colorWithRed:0.176 green:0.306 blue:0.431 alpha:1.];
	tweetView.textFont = [UIFont systemFontOfSize:12];
	tweetView.urlColor = [UIColor colorWithRed:0.153 green:0.431 blue:0.702 alpha:1.];
	tweetView.hashtagColor = [UIColor colorWithRed:0.518 green:0.600 blue:0.690 alpha:1.];
	tweetView.userMentionColor = [UIColor colorWithRed:0.267 green:0.349 blue:0.427 alpha:1.];
	tweetView.userMentionFont = [UIFont boldSystemFontOfSize:12];
	[self.window addSubview:tweetView];
	
	// Resize view to encompass text only
	[tweetView sizeToFit];

	// Add tap gesture handlers for parsed tweet entities
	tweetView.urlTapped = ^(WMATweetURLEntity *entity, NSUInteger numberOfTouches)
	{
		NSLog(@"Tapped entity: %@", entity);
	};
	tweetView.hashtagTapped = ^(WMATweetHashtagEntity *entity, NSUInteger numberOfTouches)
	{
		NSLog(@"Tapped entity: %@", entity);
	};
	tweetView.userMentionTapped = ^(WMATweetUserMentionEntity *entity, NSUInteger numberOfTouches)
	{
		NSLog(@"Tapped entity: %@", entity);
	};
	
	// Go!
	[self.window makeKeyAndVisible];
	return YES;
}

Manually setting .text and .entities values

If you're a masochist, you can set the .text and .entities properties manually. You'd probably only want to do this if you didn't have an NSDictionary derived from a call to Twitter's API.

One day, I might do some sort of regex parsing so the manual entity creation isn't required (although you'll miss out on the good stuff that Twitter's API provides - original URLs, display URLs, full names for @mentions etc etc etc).

Example:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
	// Set up window
	self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	self.window.backgroundColor = [UIColor whiteColor];
	
	// Build & add tweet view - let's emulate Tweetbot
	WMATweetView *tweetView = [[WMATweetView alloc] initWithFrame:CGRectMake(10, 30, 300, 300)];
	tweetView.text = @"Tweet with a link http://t.co/dQ06Fbx3, screen name @wemakeapps, #hashtag, more text, another link http://t.co/9GQa6ycA @ZarroBoogs #ios moo";
	// Add entities (well, the last two anyway)
	NSMutableArray *entities = [NSMutableArray array];
	[entities addObject:[WMATweetUserMentionEntity entityWithScreenName:@"ZarroBoogs" name:@"Mark Beaton" idString:@"547490130" start:120 end:131]];
	[entities addObject:[WMATweetHashtagEntity entityWithText:@"ios" start:132 end:136]];
	tweetView.entities = entities;
	
	tweetView.backgroundColor = [UIColor colorWithRed:0.906 green:0.945 blue:0.980 alpha:1.];
	tweetView.textColor = [UIColor colorWithRed:0.176 green:0.306 blue:0.431 alpha:1.];
	tweetView.textFont = [UIFont systemFontOfSize:12];
	tweetView.urlColor = [UIColor colorWithRed:0.153 green:0.431 blue:0.702 alpha:1.];
	tweetView.hashtagColor = [UIColor colorWithRed:0.518 green:0.600 blue:0.690 alpha:1.];
	tweetView.userMentionColor = [UIColor colorWithRed:0.267 green:0.349 blue:0.427 alpha:1.];
	tweetView.userMentionFont = [UIFont boldSystemFontOfSize:12];
	[self.window addSubview:tweetView];
	
	// Resize view to encompass text only
	[tweetView sizeToFit];

	// Add tap gesture handlers for parsed tweet entities
	tweetView.urlTapped = ^(WMATweetURLEntity *entity, NSUInteger numberOfTouches)
	{
		NSLog(@"Tapped entity: %@", entity);
	};
	tweetView.hashtagTapped = ^(WMATweetHashtagEntity *entity, NSUInteger numberOfTouches)
	{
		NSLog(@"Tapped entity: %@", entity);
	};
	tweetView.userMentionTapped = ^(WMATweetUserMentionEntity *entity, NSUInteger numberOfTouches)
	{
		NSLog(@"Tapped entity: %@", entity);
	};
	
	// Go!
	[self.window makeKeyAndVisible];
	return YES;
}