-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathUIView.j
434 lines (355 loc) · 15.8 KB
/
UIView.j
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
/*
* UIView.j
* UIKit
*
* Created by Amari Robinson.
* Copyright 2011, Amari Robinson.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "UIResponder.j"
@import "UIColor.j"
@import "UIGestureRecognizer.j"
@import "UIViewLayer.j"
/* UIViewAnimationOptions */
var UIViewAnimationOptionLayoutSubviews = 1 << 0,
UIViewAnimationOptionAllowUserInteraction = 1 << 1,
UIViewAnimationOptionBeginFromCurrentState = 1 << 2,
UIViewAnimationOptionRepeat = 1 << 3,
UIViewAnimationOptionAutoreverse = 1 << 4,
UIViewAnimationOptionOverrideInheritedDuration = 1 << 5,
UIViewAnimationOptionOverrideInheritedCurve = 1 << 6,
UIViewAnimationOptionAllowAnimatedContent = 1 << 7,
UIViewAnimationOptionShowHideTransitionViews = 1 << 8,
UIViewAnimationOptionCurveEaseInOut = 0 << 16,
UIViewAnimationOptionCurveEaseIn = 1 << 16,
UIViewAnimationOptionCurveEaseOut = 2 << 16,
UIViewAnimationOptionCurveLinear = 3 << 16,
UIViewAnimationOptionTransitionNone = 0 << 20,
UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20,
UIViewAnimationOptionTransitionFlipFromRight = 2 << 20,
UIViewAnimationOptionTransitionCurlUp = 3 << 20,
UIViewAnimationOptionTransitionCurlDown = 4 << 20;
/* UIViewContentMode */
var UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit,
UIViewContentModeScaleAspectFill,
UIViewContentModeRedraw,
UIViewContentModeCenter,
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight;
/* UIViewAutoresizing */
var UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5;
/* UIViewAnimationTransition */
var UIViewAnimationTransitionNone,
UIViewAnimationTransitionFlipFromLeft,
UIViewAnimationTransitionFlipFromRight,
UIViewAnimationTransitionCurlUp,
UIViewAnimationTransitionCurlDown;
@implementation UIView : UIResponder {
/* Configuring a View’s Visual Appearance */
UIColor _backgroundColor @accessors(property=ackgroundColor:);
BOOL _hidden @accessors(getter=isHidden;setter=setHidden:);
CGFloat _alpha @accessors(property=alpha);
BOOL _opaque @accessors(property=opaque);
BOOL _clipsToBounds @accessors(property=clipsToBounds);
UIViewContentMode _contentMode @accessors(propertyContentMode);
BOOL _clearsContextBeforeDrawing @accessors(property=clearsContextBeforeDrawing)
CALayer _layer @accessors(getter=layer;setter=_setLayer:);
/* Configuring the Event-Related Behavior*/
BOOL _userInteractionEnabled @accessors(getter=isUserInteractionEnabled;setter=setUserInteractionEnabled:);
BOOL _multipleTouchEnabled @accessors(getter=isMultipleTouchEnabled;setter=setMultipleTouchEnabled:);
BOOL _exclusiveTouch @accessors(getter=isExclusiveTouch;setter=setExclusiveTouch:);
/* Configuring the Bounds and Frame Rectangles */
CGRect _frame @accessors(property=frame);
CGRect _bounds @accessors(property=bounds);
CGPoint _center @accessors(property=center);
CGAffineTransform _transform @accessors(property=transform);
/* Configuring the Resizing Behavior */
UIViewAutoresizing _autoresizingMask @accessors(property=autoresizingMask);
BOOL _autoresizesSubviews @accessors(property=autoresizesSubviews);
UIViewContentMode _contentMode @accessors(property=contentMode);
CGRect _contentStretch @accessors(property=contentStretch);
/* Managing the View Hierarchy */
UIView _superview @accessors(getter=superview,setter=_setSuperview:);
CPArray _subviews @accessors(getter=subviews,setter=_setSubviews:);
UIWindow _window @accessors(getter=window,setter=_setWindow:);
/* Drawing and Updating the View */
CGFloat _contentScaleFactor @accessors(property=contentScaleFactor);
/* Managing Gesture Recognizers */
CPArray _gestureRecognizers @accessors(property=gestureRecognizers);
/* Identifying the View at Runtime */
CPInteger _tag @accesors(property=tag);
/* Touches and other stuff */
CPSet _touches @accessors(property=allTouches);
}
- (id)initWithFrame:(CGRect)aRect {
/* Initializes and returns a newly allocated view
object with the specified frame rectangle. */
if (self = [super init]) {
_backgroundColor = nil;
_clearsContextBeforeDrawing = YES;
_opaque = NO;
_layer = [[self layerClass] layer];
_userInteractionEnabled = YES;
_transform = CGAffineTransformIdentity;
_autoresizesSubviews = YES;
_superview = nil;
_subviews = [CPArray array];
_window = nil;
_gestureRecognizers = [CPArray array];
_layer = [[UIViewLayer alloc] init];
[_layer setView:self];
}
return self;
}
/* Configuring a View’s Visual Appearance */
+ (Class)layerClass {
return [_layer class];
}
/* Configuring the Bounds and Frame Rectangles */
- (void)setBounds:(CGRect)aRect {
_frame.size = aRect.size;
_bounds = aRect;
}
- (void)setCenter:(CGPoint)aPoint {
_frame.origin.x = aPoint.x - _frame.size.width/2;
_frame.origin.y = aPoint.y - _frame.size.height/2;
_center = aPoint;
}
/* Configuring the Resizing Behavior */
- (CGSize)sizeThatFits:(CGSize)size {
}
- (void)sizeToFit {
}
/* Managing the View Hierarchy */
- (void)addSubview:(UIView)view {
[view setNextResponder:self];
[view _setSuperview:self];
[view _setWindow:_window];
[_subviews addObject:view];
[self setNeedsDisplay];
}
- (void)bringSubviewToFront:(UIView)view {
}
- (void)sendSubviewToBack:(UIView)view {
}
- (void)removeFromSuperview {
[[_superview subviews] removeObject:self];
[_superview setNeedsDisplay];
_superview = nil;
_window = nil;
[self setNextResponder:nil];
}
- (void)insertSubview:(UIView)view atIndex:(NSInteger)index {
[view setNextResponder:self];
[view _setSuperview:self];
[view _setWindow:_window];
[_subviews insertObject:view atIndex:index];
[self setNeedsDisplay];
}
- (void)insertSubview:(UIView)view aboveSubview:(UIView)siblingSubview {
[_layer setZPosition:([[siblingSubview layer] ZPosition] + 1)];
[_superview addSubview:view];
}
- (void)insertSubview:(UIView)view belowSubview:(UIView)siblingSubview {
[_layer setZPosition:([[siblingSubview layer] ZPosition] - 1)];
[_superview addSubview:view];
}
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2 {
var _view1 = [_subviews objectAtIndex:index1];
var _view2 = [_subviews objectAtIndex:index2];
[_subviews removeObjectAtIndex:index1];
[_subviews insertObject:_view2 atIndex:index1];
[_subviews removeObjectAtIndex:index2];
[_subviews insertObject:_view1 atIndex:index2];
}
- (BOOL)isDescendantOfView:(UIView)view {
if (view != self) {
var _s = [view subviews];
for (var s = 0, ss = [[view subviews] count]; s < ss; s++) {
if ([self isDescendantOfView:_s[s]] == YES)
return YES;
}
return NO;
}
return YES;
}
/* Laying out Subviews */
- (void)layoutSubviews {
}
- (void)setNeedsLayout {
}
- (void)layoutIfNeeded {
}
/* Drawing and Updating the View */
- (void)drawRect:(CGRect)rect {
var ctx = [CGGraphicsContext currentGraphicsContext];
[_layer drawInContext:ctx];
// [_layer renderInContext:ctx]; If we want to stay up to date with Apple's API
}
- (void)setNeedsDisplay {
[_layer setNeedsDisplay];
}
- (void)setNeedsDisplayInRect:(CGRect)invalidRect {
[_layer setNeedsDisplayInRect:invalidRect];
}
/* Managing Gesture Recognizers */
- (void)addGestureRecognizer:(UIGestureRecognizer)gestureRecognizer {
[gestureRecognizer _setView:self];
[_gestureRecognizers addObject:gestureRecognizer];
}
- (void)removeGestureRecognizer:(UIGestureRecognizer)gestureRecognizer {
[_gestureRecognizers removeObject:gestureRecognizer];
[gestureRecognizer release];
}
/* Animating Views with Blocks */
+ (void)animateWithDuration:(CPTimeInterval)duration delay:(CPTimeInterval)delay options:(UIViewAnimationOptions)options animations:(JSObject)animations completion:(JSObject)completion {
/* This method initiates a set of animations to perform on the view.
The block object in the animations parameter contains the code for
animating the properties of one or more views. */
// But since blocks don't exist in Objective-J, these are functions!!
}
+ (void)animateWithDuration:(CPTimeInterval)duration animations:(JSObject)animations completion:(JSObject)completion {
/* This method performs the specified animations immediately using the UIViewAnimationOptionCurveEaseInOut and UIViewAnimationOptionTransitionNone animation options.
For example, if you want to fade a view until it is totally transparent and then remove it from your view hierarchy, you could use code similar to the following:
[UIView animateWithDuration:0.2
animations: function(void) {view.alpha = 0.0;}
completion: function(finished){ [view removeFromSuperview]; }];
*/
}
+ (void)animateWithDuration:(CPTimeInterval)duration animations:(JSObject)animations {
/* This method performs the specified animations immediately using the
UIViewAnimationOptionCurveEaseInOut and UIViewAnimationOptionTransitionNone
animation options. */
}
+ (void)transitionWithView:(UIView)view duration:(CPTimeInterval)duration options:(UIViewAnimationOptions)options animations:(JSObject)animations completion:(JSObject)completion {
/* This method applies a transition to the specified view so that you can make state changes to it.
The block you specify in the animations parameter contains whatever state changes you want to make.
You can use this block to add, remove, show, or hide subviews of the specified view.
If you want to incorporate other animatable changes, you must include the UIViewAnimationOptionAllowAnimatedContent
key in the options parameter.
The following code creates a flip transition for the specified container view. At the appropriate point in the transition, one subview is removed and another is added to the container view. This makes it look as if a new view was flipped into place with the new subview, but really it is just the same view animated back into place with a new configuration.
[UIView transitionWithView:containerView
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:function(void) { [fromView removeFromSuperview]; [containerView addSubview:toView]; }
completion:NULL];*/
}
+ (void)transitionFromView:(UIView)fromView toView:(UIView)toView duration:(CPTimeInterval)duration options:(UIViewAnimationOptions)options completion:(JSObject)completion {
/* This method provides a simple way to transition from the view in the fromView parameter to the view in the toView parameter.
By default, the view in fromView is replaced in the view hierarchy by the view in toView. If both views are already part of
your view hierarchy, you can include the UIViewAnimationOptionShowHideTransitionViews option in the options parameter to
simply hide or show them.
This method modifies the views in their view hierarchy only. It does not modify your application’s view controllers in any way.
For example, if you use this method to change the root view displayed by a view controller, it is your responsibility to update
the view controller appropriately to handle the change.
The view transition starts immediately unless another animation is already in-flight, in which case it starts immediately after the current animation finishes.*/
}
/* Identifying the View at Runtime */
- (UIView)viewWithTag:(CPInteger)tag {
if (_tag != tag) {
for (var t = 0, tt = [_subviews count]; t < tt; t++) {
if ([[_subviews objectAtIndex:t] viewWithTag:tag] != nil)
return [[_subviews objectAtIndex:t] viewWithTag:tag];
}
return nil;
}
return self;
}
/* Converting Between View Coordinate Systems */
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView)view {
return [[self layer] convertPoint:point toLayer:[view layer]]; //Pure Convience
}
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView)view {
return [[self layer] convertPoint:point fromLayer:[view layer]]; //Pure Convience
}
- (CGRect)convertRect:(CGRect)rect toView:(UIView)view {
return [[self layer] convertRect:rect toLayer:[view layer]]; //Pure Convience
}
- (CGRect)convertRect:(CGRect)rect fromView:(UIView)view {
return [[self layer] convertRect:rect fromLayer:[view layer]]; //Pure Convience
}
/* Hit Testing in a View */
- (UIView)hitTest:(CGPoint)point withEvent:(UIEvent)event {
var p = [[self layer] convertPoint:point toLayer:[[self layer] superlayer]],
l = [[self layer] hitTest:p];
if (l != nil)
return [l view];
return nil;
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent)event {
if (_hidden || _alpha < 0.01 || _userInteractionEnabled == NO)
return NO;
return [[self layer] containsPoint:point];
}
/* Ending a View Editing Session */
- (BOOL)endEditing:(BOOL)force {
/* This method looks at the current view and its subview hierarchy for the text field that is currently the first responder.
If it finds one, it asks that text field to resign as first responder. If the force parameter is set to YES, the
text field is never even asked; it is forced to resign. */
return YES;
}
/* Observing View-Related Changes */
- (void)didAddSubview:(UIView)subview {
/* The default implementation of this method does nothing. Subclasses can override it to perform additional actions
when subviews are added.This method is called in response to adding a subview using any of the relevant view methods. */
}
- (void)willRemoveSubview:(UIView)subview {
/* The default implementation of this method does nothing. Subclasses can override it to perform additional actions
whenever subviews are removed. This method is called when the subview’s superview changes or when the subview is
removed from the view hierarchy completely. */
}
- (void)willMoveToSuperview:(UIView)newSuperview {
/* The default implementation of this method does nothing. Subclasses can override it to perform additional
actions whenever the superview changes. */
}
- (void)didMoveToSuperview {
/* The default implementation of this method does nothing. Subclasses can override it to perform additional
actions whenever the superview changes. */
}
- (void)willMoveToWindow:(UIWindow)newWindow {
/* The window object that will be at the root of the receiver's new view hierarchy. This parameter may be nil. */
}
- (void)didMoveToWindow {
/* The default implementation of this method does nothing. Subclasses can override it to perform additional
actions whenever the window changes. */
}
/* UIResponder */
- (void)touchesBegan:(CPSet)touches withEvent:(UIEvent)anEvent
{
_gestureRecognizers.forEach(function (x) { [x touchesBegan:touches withEvent:anEvent] });
}
- (void)touchesEnded:(CPSet)touches withEvent:(UIEvent)anEvent
{
_gestureRecognizers.forEach(function (x) { [x touchesEnded:touches withEvent:anEvent] });
}
- (void)touchesMoved:(CPSet)touches withEvent:(UIEvent)anEvent
{
_gestureRecognizers.forEach(function (x) { [x touchesMoved:touches withEvent:anEvent] });
}
@end