Skip to content

Commit

Permalink
Added custom drawing to layout example.
Browse files Browse the repository at this point in the history
  • Loading branch information
macguru committed Sep 29, 2013
1 parent e9064d9 commit 30def2d
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 60 deletions.
6 changes: 6 additions & 0 deletions TextKitDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
5041487517F8418B008D88C6 /* TKDLayoutingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5041487417F8418B008D88C6 /* TKDLayoutingViewController.m */; };
5041487717F843EA008D88C6 /* layout.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5041487617F843EA008D88C6 /* layout.txt */; };
5041487A17F844E5008D88C6 /* TKDLinkDetectingTextStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 5041487917F844E5008D88C6 /* TKDLinkDetectingTextStorage.m */; };
5041487D17F84DB2008D88C6 /* TKDOutliningLayoutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5041487C17F84DB2008D88C6 /* TKDOutliningLayoutManager.m */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -71,6 +72,8 @@
5041487617F843EA008D88C6 /* layout.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = layout.txt; sourceTree = "<group>"; };
5041487817F844E5008D88C6 /* TKDLinkDetectingTextStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TKDLinkDetectingTextStorage.h; sourceTree = "<group>"; };
5041487917F844E5008D88C6 /* TKDLinkDetectingTextStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TKDLinkDetectingTextStorage.m; sourceTree = "<group>"; };
5041487B17F84DB2008D88C6 /* TKDOutliningLayoutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TKDOutliningLayoutManager.h; sourceTree = "<group>"; };
5041487C17F84DB2008D88C6 /* TKDOutliningLayoutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TKDOutliningLayoutManager.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -207,6 +210,8 @@
children = (
5041487317F8418B008D88C6 /* TKDLayoutingViewController.h */,
5041487417F8418B008D88C6 /* TKDLayoutingViewController.m */,
5041487B17F84DB2008D88C6 /* TKDOutliningLayoutManager.h */,
5041487C17F84DB2008D88C6 /* TKDOutliningLayoutManager.m */,
5041487817F844E5008D88C6 /* TKDLinkDetectingTextStorage.h */,
5041487917F844E5008D88C6 /* TKDLinkDetectingTextStorage.m */,
);
Expand Down Expand Up @@ -317,6 +322,7 @@
5041486C17F81F2F008D88C6 /* TKDHighlightingTextStorage.m in Sources */,
5041486817F8112A008D88C6 /* TKDConfigurationViewController.m in Sources */,
5041483817F80E5C008D88C6 /* TKDAppDelegate.m in Sources */,
5041487D17F84DB2008D88C6 /* TKDOutliningLayoutManager.m in Sources */,
5041487A17F844E5008D88C6 /* TKDLinkDetectingTextStorage.m in Sources */,
5041486917F8112A008D88C6 /* TKDHighlightingViewController.m in Sources */,
5041487517F8418B008D88C6 /* TKDLayoutingViewController.m in Sources */,
Expand Down
19 changes: 0 additions & 19 deletions TextKitDemo/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -116,29 +116,10 @@
<view key="view" contentMode="scaleToFill" id="gMD-aP-Fq6">
<rect key="frame" x="0.0" y="0.0" width="320" height="519"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" keyboardDismissMode="interactive" translatesAutoresizingMaskIntoConstraints="NO" id="otG-vH-Joq">
<rect key="frame" x="0.0" y="20" width="320" height="499"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="0.98987746474953331" blue="0.82377890862122616" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="BOB-cu-ptZ" firstAttribute="top" secondItem="otG-vH-Joq" secondAttribute="bottom" id="Bsn-Ga-JSV"/>
<constraint firstAttribute="trailing" secondItem="otG-vH-Joq" secondAttribute="trailing" id="gX0-45-QrQ"/>
<constraint firstItem="otG-vH-Joq" firstAttribute="leading" secondItem="gMD-aP-Fq6" secondAttribute="leading" id="hKN-aA-RLw"/>
<constraint firstItem="otG-vH-Joq" firstAttribute="top" secondItem="yZO-zZ-5uU" secondAttribute="bottom" id="sep-hN-Rgf"/>
</constraints>
</view>
<extendedEdge key="edgesForExtendedLayout"/>
<tabBarItem key="tabBarItem" title="Layout" image="first" id="Z7h-1E-pvt"/>
<connections>
<outlet property="bottomInset" destination="Bsn-Ga-JSV" id="pFD-jp-E5f"/>
<outlet property="textView" destination="otG-vH-Joq" id="Jti-1J-cc8"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="3qq-4t-Ow8" sceneMemberID="firstResponder"/>
</objects>
Expand Down
4 changes: 0 additions & 4 deletions TextKitDemo/Layout/TKDLayoutingViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,4 @@
#import <UIKit/UIKit.h>

@interface TKDLayoutingViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomInset;

@end
54 changes: 18 additions & 36 deletions TextKitDemo/Layout/TKDLayoutingViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import "TKDLayoutingViewController.h"

#import "TKDLinkDetectingTextStorage.h"
#import "TKDOutliningLayoutManager.h"


@interface TKDLayoutingViewController () <NSLayoutManagerDelegate>
Expand All @@ -24,14 +25,25 @@ - (void)viewDidLoad
{
[super viewDidLoad];

// Set delegate
self.textView.layoutManager.delegate = self;

// Replace text storage
// Create componentes
_textStorage = [TKDLinkDetectingTextStorage new];
[_textStorage addLayoutManager: self.textView.layoutManager];

// Load iText
NSLayoutManager *layoutManager = [TKDOutliningLayoutManager new];
[_textStorage addLayoutManager: layoutManager];

NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize: CGSizeZero];
[layoutManager addTextContainer: textContainer];

UITextView *textView = [[UITextView alloc] initWithFrame:CGRectInset(self.view.bounds, 5, 20) textContainer: textContainer];
textView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
textView.translatesAutoresizingMaskIntoConstraints = YES;
[self.view addSubview: textView];


// Set delegate
layoutManager.delegate = self;

// Load layout text
[_textStorage replaceCharactersInRange:NSMakeRange(0, 0) withString:[NSString stringWithContentsOfURL:[NSBundle.mainBundle URLForResource:@"layout" withExtension:@"txt"] usedEncoding:NULL error:NULL]];
}

Expand Down Expand Up @@ -60,34 +72,4 @@ - (CGFloat)layoutManager:(NSLayoutManager *)layoutManager paragraphSpacingAfterG
return 10;
}


#pragma mark - Keyboard status

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear: animated];

[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(keyboardWillShowOrHide:) name:UIKeyboardWillShowNotification object:nil];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(keyboardWillShowOrHide:) name:UIKeyboardDidHideNotification object:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear: animated];

[NSNotificationCenter.defaultCenter removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[NSNotificationCenter.defaultCenter removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (void)keyboardWillShowOrHide:(NSNotification *)notification
{
CGFloat newInset;
if ([notification.name isEqualToString: UIKeyboardWillShowNotification])
newInset = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
else
newInset = 0;

[self.bottomInset setConstant: newInset];
}

@end
2 changes: 2 additions & 0 deletions TextKitDemo/Layout/TKDLinkDetectingTextStorage.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str
NSRange paragaphRange = [self.string paragraphRangeForRange: NSMakeRange(range.location, str.length)];
[self removeAttribute:NSLinkAttributeName range:paragaphRange];
[self removeAttribute:NSBackgroundColorAttributeName range:paragaphRange];
[self removeAttribute:NSUnderlineStyleAttributeName range:paragaphRange];

// Find all iWords in range
[linkDetector enumerateMatchesInString:self.string options:0 range:paragaphRange usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
// Add red highlight color
[self addAttribute:NSLinkAttributeName value:result.URL range:result.range];
[self addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:result.range];
[self addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:result.range];
}];
}

Expand Down
13 changes: 13 additions & 0 deletions TextKitDemo/Layout/TKDOutliningLayoutManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// TKDOutliningLayoutManager.h
// TextKitDemo
//
// Created by Max Seelemann on 29.09.13.
// Copyright (c) 2013 Max Seelemann. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface TKDOutliningLayoutManager : NSLayoutManager

@end
45 changes: 45 additions & 0 deletions TextKitDemo/Layout/TKDOutliningLayoutManager.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// TKDOutliningLayoutManager.m
// TextKitDemo
//
// Created by Max Seelemann on 29.09.13.
// Copyright (c) 2013 Max Seelemann. All rights reserved.
//

#import "TKDOutliningLayoutManager.h"

@implementation TKDOutliningLayoutManager

- (void)drawUnderlineForGlyphRange:(NSRange)glyphRange underlineType:(NSUnderlineStyle)underlineVal baselineOffset:(CGFloat)baselineOffset lineFragmentRect:(CGRect)lineRect lineFragmentGlyphRange:(NSRange)lineGlyphRange containerOrigin:(CGPoint)containerOrigin
{
// Left border (== position) of first underlined glyph
CGFloat firstPosition = [self locationForGlyphAtIndex: glyphRange.location].x;

// Right border (== position + width) of last underlined glyph
CGFloat lastPosition;

// When link is not the last text in line, just use the location of the next glyph
if (NSMaxRange(glyphRange) < NSMaxRange(lineGlyphRange)) {
lastPosition = [self locationForGlyphAtIndex: NSMaxRange(glyphRange)].x;
}
// Otherwise get the end of the actually used rect
else {
lastPosition = [self lineFragmentUsedRectForGlyphAtIndex:NSMaxRange(glyphRange)-1 effectiveRange:NULL].size.width;
}

// Inset line fragment to underlined area
lineRect.origin.x += firstPosition;
lineRect.size.width = lastPosition - firstPosition;

// Offset line by container origin
lineRect.origin.x += containerOrigin.x;
lineRect.origin.y += containerOrigin.y;

// Align line to pixel boundaries, passed rects may be
lineRect = CGRectInset(CGRectIntegral(lineRect), .5, .5);

[[UIColor greenColor] set];
[[UIBezierPath bezierPathWithRect: lineRect] stroke];
}

@end
2 changes: 1 addition & 1 deletion TextKitDemo/Texts/layout.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Lorem ipsum dolor sit amet, tomorrow consectetur adipiscing http://stackoverflow.com/questions/tagged/objective-c?sort=featured&pageSize=15 elit. Phasellus http://apple.com magna dolor, volutpat http://www.objc.io/issue-4/editorial.html a ipsum et, porttitor molestie justo. Vestibulum sed augue malesuada, congue magna sed, fringilla ligula. Sed aliquet porta vestibulum. Phasellus gravida elit ut ligula vulputate fringilla. Pellentesque sit amet dolor pulvinar, dictum eros non, suscipit purus. Aenean metus mi, sodales ut augue in, varius sagittis mi. Sed semper est vel placerat scelerisque. In hac habitasse platea dictumst. Mauris auctor accumsan sagittis. Etiam interdum ante in condimentum iaculis. Aliquam porta facilisis lorem in auctor. Nullam non tortor eget urna iaculis faucibus et in augue. Integer nec libero placerat magna rhoncus ultrices eu venenatis massa. Suspendisse ullamcorper molestie lorem eget consequat.
Lorem ipsum dolor sit amet, tomorrow consectetur adipiscing http://stackoverflow.com/questions/tagged/objective-c?sort=featured&pageSize=15 elit. dictum eros non, suscipit purus. Aenean metus mi, sodales ut augue in, varius sagittis http://apple.com magnadolortligulavulputatefringilla. Pellentesque sit amet dolor pulvinar, dictum eros non, suscipit purus. Aenean metus mi, sodales ut augue in, varius sagittis mi. Sed semper est vel placerat scelerisque. In hac habitasse http://www.objc.io/issue-4/editorial.html ipsum eterant, porttitor molestie justo. Vestibulum sed augue malesuada, congue magna sed, fringilla ligula. Sed aliquet porta vestibulum. Phasellus gravida elit uatea dictumst. Mauris auctor accumsan sagittis. Etiam interdum ante in condimentum iaculis. Aliquam porta facilisis lorem in auctor. Nullam non tortor eget urna iaculis faucibus et in augue. Integer nec libero placerat magna rhoncus ultrices eu venenatis massa. Suspendisse ullamcorper molestie lorem eget consequat.

Duis viverra, nibh vitae dapibus aliquet, dui sapien tristique enim, sit amet lacinia justo ligula sit amet arcu. Donec consequat, sapien nec varius placerat, lectus ante sollicitudin lorem, mattis dictum nisl diam id massa. Curabitur mattis turpis ac est cursus sagittis. Nunc in mattis mi, eu aliquet magna. Suspendisse arcu dolor, tincidunt nec eros in, dapibus auctor risus. Curabitur auctor sit amet eros sit amet imperdiet. Etiam et eros tempus, posuere justo ut, ultrices risus. Cras fringilla risus sapien, sit amet congue mauris fringilla quis. Mauris molestie tincidunt iaculis. Mauris nunc ante, faucibus et eros sed, imperdiet congue justo. Suspendisse euismod rhoncus sollicitudin. Maecenas non pretium nulla.

0 comments on commit 30def2d

Please sign in to comment.