forked from facebookarchive/three20
/
TTTableView.m
171 lines (138 loc) · 4.84 KB
/
TTTableView.m
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#import "Three20/TTTableView.h"
#import "Three20/TTStyledNode.h"
#import "Three20/TTStyledTextLabel.h"
#import "Three20/TTTableViewDelegate.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
// global
static const CGFloat kCancelHighlightThreshold = 4;
///////////////////////////////////////////////////////////////////////////////////////////////////
@implementation TTTableView
@synthesize highlightedLabel = _highlightedLabel;
///////////////////////////////////////////////////////////////////////////////////////////////////
// private
- (void)hideMenuAnimationDidStop:(NSString*)animationID finished:(NSNumber*)finished
context:(void*)context {
UIView* menuView = (UIView*)context;
[menuView removeFromSuperview];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// NSObject
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
if (self = [super initWithFrame:frame style:style]) {
_highlightedLabel = nil;
_highlightStartPoint = CGPointZero;
_menuView = nil;
_menuCell = nil;
}
return self;
}
- (void)dealloc {
TT_RELEASE_MEMBER(_highlightedLabel);
TT_RELEASE_MEMBER(_menuView);
TT_RELEASE_MEMBER(_menuCell);
[super dealloc];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// UIResponder
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
[super touchesBegan:touches withEvent:event];
if (_highlightedLabel) {
UITouch* touch = [touches anyObject];
_highlightStartPoint = [touch locationInView:self];
}
if ([self.delegate isKindOfClass:[TTTableViewDelegate class]]) {
TTTableViewDelegate* delegate = (TTTableViewDelegate*)self.delegate;
[delegate.controller touchesBegan:touches withEvent:event];
}
if (_menuView) {
UITouch* touch = [touches anyObject];
CGPoint point = [touch locationInView:_menuView];
if (point.y < 0 || point.y > _menuView.height) {
[self hideMenu:YES];
} else {
UIView* hit = [_menuView hitTest:point withEvent:event];
if (![hit isKindOfClass:[UIControl class]]) {
[self hideMenu:YES];
}
}
}
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
[super touchesEnded:touches withEvent:event];
if (_highlightedLabel) {
TTStyledElement* element = _highlightedLabel.highlightedNode;
[element performDefaultAction];
} else {
if ([self.delegate isKindOfClass:[TTTableViewDelegate class]]) {
TTTableViewDelegate* delegate = (TTTableViewDelegate*)self.delegate;
[delegate.controller touchesEnded:touches withEvent:event];
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// UITableView
- (void)reloadData {
if (_menuView) {
[self hideMenu:NO];
}
[super reloadData];
}
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated
scrollPosition:(UITableViewScrollPosition)scrollPosition {
if (!_highlightedLabel) {
[super selectRowAtIndexPath:indexPath animated:animated scrollPosition:scrollPosition];
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// public
- (void)setHighlightedLabel:(TTStyledTextLabel*)label {
if (label != _highlightedLabel) {
_highlightedLabel.highlightedNode = nil;
[_highlightedLabel release];
_highlightedLabel = [label retain];
}
}
- (void)showMenu:(UIView*)view forCell:(UITableViewCell*)cell animated:(BOOL)animated {
[self hideMenu:YES];
_menuView = [view retain];
_menuCell = [cell retain];
// Insert the cell below all content subviews
[_menuCell.contentView insertSubview:_menuView atIndex:0];
if (animated) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:TT_FAST_TRANSITION_DURATION];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
}
// Move each content subview down, revealing the menu
for (UIView* view in _menuCell.contentView.subviews) {
if (view != _menuView) {
view.left -= _menuCell.contentView.width;
}
}
if (animated) {
[UIView commitAnimations];
}
}
- (void)hideMenu:(BOOL)animated {
if (_menuView) {
if (animated) {
[UIView beginAnimations:nil context:_menuView];
[UIView setAnimationDuration:TT_FAST_TRANSITION_DURATION];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(hideMenuAnimationDidStop:finished:context:)];
}
for (UIView* view in _menuCell.contentView.subviews) {
if (view != _menuView) {
view.left += _menuCell.contentView.width;
}
}
if (animated) {
[UIView commitAnimations];
} else {
[_menuView removeFromSuperview];
}
TT_RELEASE_MEMBER(_menuView);
TT_RELEASE_MEMBER(_menuCell);
}
}
@end