forked from facebook/componentkit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCKTextComponentLayerHighlighter.mm
85 lines (70 loc) · 2.56 KB
/
CKTextComponentLayerHighlighter.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "CKTextComponentLayerHighlighter.h"
#import <ComponentKit/CKAssert.h>
#import <ComponentKit/CKHighlightOverlayLayer.h>
#import <ComponentKit/CKTextKitRenderer+Positioning.h>
#import <ComponentKit/CKTextKitRenderer.h>
#import "CKTextComponentLayer.h"
@implementation CKTextComponentLayerHighlighter
{
__weak CKTextComponentLayer *_textComponentLayer;
CKHighlightOverlayLayer *_highlightOverlayLayer;
}
- (instancetype)initWithTextComponentLayer:(CKTextComponentLayer *)textComponentLayer
{
if (self = [super init]) {
_textComponentLayer = textComponentLayer;
}
return self;
}
- (void)setHighlightedRange:(NSRange)highlightedRange
{
CKAssertMainThread();
if (!NSEqualRanges(_highlightedRange, highlightedRange)) {
_highlightedRange = highlightedRange;
if (NSEqualRanges(_highlightedRange, CKTextComponentLayerInvalidHighlightRange)) {
// We should hide the overlay layer
if (_highlightOverlayLayer) {
[CATransaction begin];
[CATransaction setDisableActions:YES];
[_highlightOverlayLayer removeFromSuperlayer];
_highlightOverlayLayer = nil;
[CATransaction commit];
}
} else {
NSArray *rects = [_textComponentLayer.renderer rectsForTextRange:_highlightedRange measureOption:CKTextKitRendererMeasureOptionBlock];
[CATransaction begin];
[CATransaction setDisableActions:YES];
if (_highlightOverlayLayer) {
[_highlightOverlayLayer removeFromSuperlayer];
}
_highlightOverlayLayer = [[CKHighlightOverlayLayer alloc] initWithRects:rects targetLayer:_textComponentLayer];
CALayer *highlightContainerLayer = _textComponentLayer;
CALayer *superlayer;
while (!highlightContainerLayer.ck_allowsHighlightDrawing && (superlayer = highlightContainerLayer.superlayer) != nil) {
highlightContainerLayer = superlayer;
}
_highlightOverlayLayer.frame = highlightContainerLayer.bounds;
[highlightContainerLayer addSublayer:_highlightOverlayLayer];
[CATransaction commit];
}
}
}
- (void)layoutHighlight
{
if (_highlightOverlayLayer) {
[CATransaction begin];
[CATransaction setDisableActions:YES];
_highlightOverlayLayer.frame = _highlightOverlayLayer.superlayer.bounds;
[CATransaction commit];
}
}
@end