Skip to content

Commit

Permalink
Added syntax highlighting for code snippets in Programming Guide
Browse files Browse the repository at this point in the history
  • Loading branch information
zen4ever committed Nov 28, 2013
1 parent 518add3 commit dc1ab81
Showing 1 changed file with 78 additions and 66 deletions.
144 changes: 78 additions & 66 deletions Documentation/Programming Guide-template.markdown
Expand Up @@ -9,13 +9,15 @@ Smoke Test
After having integrated DTCoreText and its dependencies into your project you should be able to build your app be able to use DTCoreText functionality. As a quick *Smoke Test* - to see if all is setup correctly - you can test your setup by adding this code to your app delegate:


#import "DTCoreText.h"
```objective-c
#import "DTCoreText.h"

NSString *html = @"<p>Some Text</p>";
NSData *data = [html dataUsingEncoding:NSUTF8StringEncoding];

NSAttributedString *attrString = [[NSAttributedString alloc] initWithHTMLData:data documentAttributes:NULL];
NSLog(@"%@", attrString);
NSString *html = @"<p>Some Text</p>";
NSData *data = [html dataUsingEncoding:NSUTF8StringEncoding];

NSAttributedString *attrString = [[NSAttributedString alloc] initWithHTMLData:data documentAttributes:NULL];
NSLog(@"%@", attrString);
```
You should see that this executes and that the NSLog outputs a description of the generated attributed string.
Expand All @@ -30,8 +32,10 @@ For most normal use cases you can use the overrides plist that is part of the DT
If you don't know the set of fonts used by your app you can trigger an asynchronous pre-loading of the internal lookup table. To start the loading process you add the following to your app delegate.
// preload font matching table
[DTCoreTextFontDescriptor asyncPreloadFontLookupTable];
```objective-c
// preload font matching table
[DTCoreTextFontDescriptor asyncPreloadFontLookupTable];
```
Calling this does not replace entries already existing in the lookup table, for example loaded from the `DTCoreTextFontOverrides.plist` included in the app bundle.

Expand All @@ -40,7 +44,9 @@ Setting a Fallback Font Family

When encountering a font family in HTML that is not known to the system the fallback font family is used. This can be set like this:

[DTCoreTextFontDescriptor setFallbackFontFamily:@"Helvetica Neue"];
```objective-c
[DTCoreTextFontDescriptor setFallbackFontFamily:@"Helvetica Neue"];
```
Note that the font family name must be valid on the system that this run on, either because it is a system font or a font you have installed at runtime. If you try to set an invalid font family name an exception will be thrown.
Expand All @@ -49,55 +55,61 @@ Getting a Tapped Word
To retrieve the word a user tapped on you get the closest cursor position to the tapped point. Then you iterate over the plain text's words until you find the one that contains the cursor position's string index.
- (void)handleTap:(UITapGestureRecognizer *)gesture
```objective-c
- (void)handleTap:(UITapGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateRecognized)
{
if (gesture.state == UIGestureRecognizerStateRecognized)
{
CGPoint location = [gesture locationInView:_textView];
NSUInteger tappedIndex = [_textView closestCursorIndexToPoint:location];
__block NSRange wordRange = NSMakeRange(0, 0);
[plainText enumerateSubstringsInRange:NSMakeRange(0, [plainText length]) options:NSStringEnumerationByWords usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if (NSLocationInRange(tappedIndex, enclosingRange))
{
*stop = YES;
wordRange = substringRange;
}
}];
NSString *word = [plainText substringWithRange:wordRange];
NSLog(@"%d: '%@' word: '%@'", tappedIndex, tappedChar, word);
}
CGPoint location = [gesture locationInView:_textView];
NSUInteger tappedIndex = [_textView closestCursorIndexToPoint:location];
__block NSRange wordRange = NSMakeRange(0, 0);
[plainText enumerateSubstringsInRange:NSMakeRange(0, [plainText length]) options:NSStringEnumerationByWords usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if (NSLocationInRange(tappedIndex, enclosingRange))
{
*stop = YES;
wordRange = substringRange;
}
}];
NSString *word = [plainText substringWithRange:wordRange];
NSLog(@"%d: '%@' word: '%@'", tappedIndex, tappedChar, word);
}
}
```


Visible String Range
--------------------

To retrieve the string range in the `NSAttributedString` you set on an DTAttributedTextView you have to get the scroll view bounds. Then you retrieve an array of lines visible in this rectangle from the DTCoreTextLayoutFrame. Finally you retrieve and create a union of the string ranges.

CGRect visibleRect = _textView.bounds;
NSArray *visibleLines = [_textView.attributedTextContentView.layoutFrame linesVisibleInRect:visibleRect];

NSRange stringRange = [visibleLines[0] stringRange];
stringRange = NSUnionRange([[visibleLines lastObject] stringRange], stringRange);

NSLog(@"visible string range: %@", NSStringFromRange(stringRange));
```objective-c
CGRect visibleRect = _textView.bounds;
NSArray *visibleLines = [_textView.attributedTextContentView.layoutFrame linesVisibleInRect:visibleRect];

NSRange stringRange = [visibleLines[0] stringRange];
stringRange = NSUnionRange([[visibleLines lastObject] stringRange], stringRange);

NSLog(@"visible string range: %@", NSStringFromRange(stringRange));
```
Determing Size Required for an Attributed String
------------------------------------------------
When creating a DTCoreTextLayoutFrame you can specify the maximum width and height that should be filled with text. If you specify `CGFLOAT_WIDTH_UNKNOWN` for the frame size width then the needed with will be calculated. If you specify `CGFLOAT_HEIGHT_UNKNOWN` the height will be calculated. You can get the needed size from the layoutFrame's frame property.
NSAttributedString *attributedString = ...
DTCoreTextLayouter *layouter = [[DTCoreTextLayouter alloc] initWithAttributedString:attributedString];

CGRect maxRect = CGRectMake(10, 20, CGFLOAT_WIDTH_UNKNOWN, CGFLOAT_HEIGHT_UNKNOWN);
NSRange entireString = NSMakeRange(0, [attributedString length]);
DTCoreTextLayoutFrame *layoutFrame = [layouter layoutFrameWithRect:maxRect range:entireString];

CGSize sizeNeeded = [layoutFrame frame].size;
```objective-c
NSAttributedString *attributedString = ...
DTCoreTextLayouter *layouter = [[DTCoreTextLayouter alloc] initWithAttributedString:attributedString];
CGRect maxRect = CGRectMake(10, 20, CGFLOAT_WIDTH_UNKNOWN, CGFLOAT_HEIGHT_UNKNOWN);
NSRange entireString = NSMakeRange(0, [attributedString length]);
DTCoreTextLayoutFrame *layoutFrame = [layouter layoutFrameWithRect:maxRect range:entireString];
CGSize sizeNeeded = [layoutFrame frame].size;
```


Displaying remote images
Expand All @@ -107,36 +119,36 @@ The best way to display remote images is to use `DTLazyImageView`.
First you will need to return `DTLazyImageView` instance for your image attachments.

```objective-c
- (UIView *)attributedTextContentView:(DTAttributedTextContentView *)attributedTextContentView viewForAttachment:(DTTextAttachment *)attachment frame:(CGRect)frame{
if([attachment isKindOfClass:[DTImageTextAttachment class]]){
DTLazyImageView *imageView = [[DTLazyImageView alloc] initWithFrame:frame];
imageView.delegate = self;

// url for deferred loading
imageView.url = attachment.contentURL;
return imageView;
}
return nil;
- (UIView *)attributedTextContentView:(DTAttributedTextContentView *)attributedTextContentView viewForAttachment:(DTTextAttachment *)attachment frame:(CGRect)frame{
if([attachment isKindOfClass:[DTImageTextAttachment class]]){
DTLazyImageView *imageView = [[DTLazyImageView alloc] initWithFrame:frame];
imageView.delegate = self;

// url for deferred loading
imageView.url = attachment.contentURL;
return imageView;
}
return nil;
}
```

Then in the in delegate method for `DTLazyImageView` reset the layout for the affected `DTAttributedContextView`.

```objective-c
- (void)lazyImageView:(DTLazyImageView *)lazyImageView didChangeImageSize:(CGSize)size {
NSURL *url = lazyImageView.url;
NSPredicate *pred = [NSPredicate predicateWithFormat:@"contentURL == %@", url];
- (void)lazyImageView:(DTLazyImageView *)lazyImageView didChangeImageSize:(CGSize)size {
NSURL *url = lazyImageView.url;
NSPredicate *pred = [NSPredicate predicateWithFormat:@"contentURL == %@", url];

// update all attachments that matching this URL
for (DTTextAttachment *oneAttachment in [self.attributedTextContentView.layoutFrame textAttachmentsWithPredicate:pred]) {
oneAttachment.originalSize = size;
}
// update all attachments that matching this URL
for (DTTextAttachment *oneAttachment in [self.attributedTextContentView.layoutFrame textAttachmentsWithPredicate:pred]) {
oneAttachment.originalSize = size;
}

// need to reset the layouter because otherwise we get the old framesetter or cached layout frames
self.attributedTextContentView.layouter = nil;
// need to reset the layouter because otherwise we get the old framesetter or cached layout frames
self.attributedTextContentView.layouter = nil;

// here we're layouting the entire string,
// might be more efficient to only relayout the paragraphs that contain these attachments
[self.attributedTextContentView relayoutText];
}
// here we're layouting the entire string,
// might be more efficient to only relayout the paragraphs that contain these attachments
[self.attributedTextContentView relayoutText];
}
```

0 comments on commit dc1ab81

Please sign in to comment.