├── .gitignore
├── .project
├── .settings
└── com.aptana.editor.common.prefs
├── CHANGELOG.txt
├── Classes
├── .gitignore
├── AsyncImageView.h
├── AsyncImageView.m
├── ComCitytelecomTiparallaxheaderModule.h
├── ComCitytelecomTiparallaxheaderModule.m
├── ComCitytelecomTiparallaxheaderModuleAssets.h
├── ComCitytelecomTiparallaxheaderModuleAssets.m
├── NSObject+JRSwizzle.h
├── NSObject+JRSwizzle.m
├── TiUIListView+ParallaxHeader.h
├── TiUIListView+ParallaxHeader.m
├── TiUIListViewProxy+ProxyParallaxHeader.h
├── TiUIListViewProxy+ProxyParallaxHeader.m
├── UIScrollView+APParallaxHeader.h
├── UIScrollView+APParallaxHeader.m
├── UITableView+HeaderSectionPosition.h
└── UITableView+HeaderSectionPosition.m
├── ComCitytelecomTiparallaxheader_Prefix.pch
├── LICENSE
├── LICENSE.txt
├── README.md
├── TiParallaxHeader.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── jameschow.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── jameschow.xcuserdatad
│ └── xcschemes
│ ├── Build & Test.xcscheme
│ ├── TiParallaxHeader.xcscheme
│ └── xcschememanagement.plist
├── assets
├── README
└── com.citytelecom.tiparallaxheader.js
├── build.py
├── com.citytelecom.tiparallaxheader-iphone-0.1.zip
├── dist
├── com.citytelecom.tiparallaxheader-iphone-0.1.zip
└── com.citytelecom.tiparallaxheader-iphone-0.2.zip
├── documentation
└── index.md
├── example
├── ParallaxImage.jpg
└── app.js
├── hooks
├── README
├── add.py
├── install.py
├── remove.py
└── uninstall.py
├── manifest
├── metadata.json
├── module.xcconfig
├── platform
└── README
├── timodule.xml
└── titanium.xcconfig
/.gitignore:
--------------------------------------------------------------------------------
1 | tmp
2 | bin
3 | build
4 | .DS_Store
5 | TiParallaxHeader.xcodeproj/project.xcworkspace/xcuserdata/jameschow.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | TiParallaxHeader
4 |
5 |
6 |
7 |
8 |
9 | com.appcelerator.titanium.core.builder
10 |
11 |
12 |
13 |
14 | com.aptana.ide.core.unifiedBuilder
15 |
16 |
17 |
18 |
19 |
20 | com.appcelerator.titanium.mobile.module.nature
21 | com.aptana.projects.webnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.settings/com.aptana.editor.common.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | selectUserAgents=com.appcelerator.titanium.mobile.module.nature\:iphone
3 |
--------------------------------------------------------------------------------
/CHANGELOG.txt:
--------------------------------------------------------------------------------
1 | Place your change log text here. This file will be incorporated with your app at package time.
--------------------------------------------------------------------------------
/Classes/.gitignore:
--------------------------------------------------------------------------------
1 | ComCitytelecomTiparallaxheader.h
2 | ComCitytelecomTiparallaxheader.m
3 |
--------------------------------------------------------------------------------
/Classes/AsyncImageView.h:
--------------------------------------------------------------------------------
1 | //
2 | // AsyncImageView.h
3 | //
4 | // Version 1.5.1
5 | //
6 | // Created by Nick Lockwood on 03/04/2011.
7 | // Copyright (c) 2011 Charcoal Design
8 | //
9 | // Distributed under the permissive zlib License
10 | // Get the latest version from here:
11 | //
12 | // https://github.com/nicklockwood/AsyncImageView
13 | //
14 | // This software is provided 'as-is', without any express or implied
15 | // warranty. In no event will the authors be held liable for any damages
16 | // arising from the use of this software.
17 | //
18 | // Permission is granted to anyone to use this software for any purpose,
19 | // including commercial applications, and to alter it and redistribute it
20 | // freely, subject to the following restrictions:
21 | //
22 | // 1. The origin of this software must not be misrepresented; you must not
23 | // claim that you wrote the original software. If you use this software
24 | // in a product, an acknowledgment in the product documentation would be
25 | // appreciated but is not required.
26 | //
27 | // 2. Altered source versions must be plainly marked as such, and must not be
28 | // misrepresented as being the original software.
29 | //
30 | // 3. This notice may not be removed or altered from any source distribution.
31 | //
32 |
33 |
34 | #import
35 | #pragma GCC diagnostic push
36 | #pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis"
37 |
38 |
39 | extern NSString *const AsyncImageLoadDidFinish;
40 | extern NSString *const AsyncImageLoadDidFail;
41 |
42 | extern NSString *const AsyncImageImageKey;
43 | extern NSString *const AsyncImageURLKey;
44 | extern NSString *const AsyncImageCacheKey;
45 | extern NSString *const AsyncImageErrorKey;
46 |
47 |
48 | @interface AsyncImageLoader : NSObject
49 |
50 | + (AsyncImageLoader *)sharedLoader;
51 | + (NSCache *)defaultCache;
52 |
53 | @property (nonatomic, strong) NSCache *cache;
54 | @property (nonatomic, assign) NSUInteger concurrentLoads;
55 | @property (nonatomic, assign) NSTimeInterval loadingTimeout;
56 |
57 | - (void)loadImageWithURL:(NSURL *)URL target:(id)target success:(SEL)success failure:(SEL)failure;
58 | - (void)loadImageWithURL:(NSURL *)URL target:(id)target action:(SEL)action;
59 | - (void)loadImageWithURL:(NSURL *)URL;
60 | - (void)cancelLoadingURL:(NSURL *)URL target:(id)target action:(SEL)action;
61 | - (void)cancelLoadingURL:(NSURL *)URL target:(id)target;
62 | - (void)cancelLoadingURL:(NSURL *)URL;
63 | - (void)cancelLoadingImagesForTarget:(id)target action:(SEL)action;
64 | - (void)cancelLoadingImagesForTarget:(id)target;
65 | - (NSURL *)URLForTarget:(id)target action:(SEL)action;
66 | - (NSURL *)URLForTarget:(id)target;
67 |
68 | @end
69 |
70 |
71 | @interface UIImageView(AsyncImageView)
72 |
73 | @property (nonatomic, strong) NSURL *imageURL;
74 |
75 | @end
76 |
77 |
78 | @interface AsyncImageView : UIImageView
79 |
80 | @property (nonatomic, assign) BOOL showActivityIndicator;
81 | @property (nonatomic, assign) UIActivityIndicatorViewStyle activityIndicatorStyle;
82 | @property (nonatomic, assign) NSTimeInterval crossfadeDuration;
83 |
84 | @end
85 |
86 |
87 | #pragma GCC diagnostic pop
88 |
89 |
--------------------------------------------------------------------------------
/Classes/AsyncImageView.m:
--------------------------------------------------------------------------------
1 | //
2 | // AsyncImageView.m
3 | //
4 | // Version 1.5.1
5 | //
6 | // Created by Nick Lockwood on 03/04/2011.
7 | // Copyright (c) 2011 Charcoal Design
8 | //
9 | // Distributed under the permissive zlib License
10 | // Get the latest version from here:
11 | //
12 | // https://github.com/nicklockwood/AsyncImageView
13 | //
14 | // This software is provided 'as-is', without any express or implied
15 | // warranty. In no event will the authors be held liable for any damages
16 | // arising from the use of this software.
17 | //
18 | // Permission is granted to anyone to use this software for any purpose,
19 | // including commercial applications, and to alter it and redistribute it
20 | // freely, subject to the following restrictions:
21 | //
22 | // 1. The origin of this software must not be misrepresented; you must not
23 | // claim that you wrote the original software. If you use this software
24 | // in a product, an acknowledgment in the product documentation would be
25 | // appreciated but is not required.
26 | //
27 | // 2. Altered source versions must be plainly marked as such, and must not be
28 | // misrepresented as being the original software.
29 | //
30 | // 3. This notice may not be removed or altered from any source distribution.
31 | //
32 |
33 |
34 | #import "AsyncImageView.h"
35 | #import
36 | #import
37 |
38 |
39 | #import
40 | #if !__has_feature(objc_arc)
41 | #error This class requires automatic reference counting
42 | #endif
43 |
44 |
45 | NSString *const AsyncImageLoadDidFinish = @"AsyncImageLoadDidFinish";
46 | NSString *const AsyncImageLoadDidFail = @"AsyncImageLoadDidFail";
47 |
48 | NSString *const AsyncImageImageKey = @"image";
49 | NSString *const AsyncImageURLKey = @"URL";
50 | NSString *const AsyncImageCacheKey = @"cache";
51 | NSString *const AsyncImageErrorKey = @"error";
52 |
53 |
54 | @interface AsyncImageConnection : NSObject
55 |
56 | @property (nonatomic, strong) NSURLConnection *connection;
57 | @property (nonatomic, strong) NSMutableData *data;
58 | @property (nonatomic, strong) NSURL *URL;
59 | @property (nonatomic, strong) NSCache *cache;
60 | @property (nonatomic, strong) id target;
61 | @property (nonatomic, assign) SEL success;
62 | @property (nonatomic, assign) SEL failure;
63 | @property (nonatomic, getter = isLoading) BOOL loading;
64 | @property (nonatomic, getter = isCancelled) BOOL cancelled;
65 |
66 | - (AsyncImageConnection *)initWithURL:(NSURL *)URL
67 | cache:(NSCache *)cache
68 | target:(id)target
69 | success:(SEL)success
70 | failure:(SEL)failure;
71 |
72 | - (void)start;
73 | - (void)cancel;
74 | - (BOOL)isInCache;
75 |
76 | @end
77 |
78 |
79 | @implementation AsyncImageConnection
80 |
81 | - (AsyncImageConnection *)initWithURL:(NSURL *)URL
82 | cache:(NSCache *)cache
83 | target:(id)target
84 | success:(SEL)success
85 | failure:(SEL)failure
86 | {
87 | if ((self = [self init]))
88 | {
89 | self.URL = URL;
90 | self.cache = cache;
91 | self.target = target;
92 | self.success = success;
93 | self.failure = failure;
94 | }
95 | return self;
96 | }
97 |
98 | - (UIImage *)cachedImage
99 | {
100 | if ([self.URL isFileURL])
101 | {
102 | NSString *path = [[self.URL absoluteURL] path];
103 | NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
104 | if ([path hasPrefix:resourcePath])
105 | {
106 | return [UIImage imageNamed:[path substringFromIndex:[resourcePath length]]];
107 | }
108 | }
109 | return [self.cache objectForKey:self.URL];
110 | }
111 |
112 | - (BOOL)isInCache
113 | {
114 | return [self cachedImage] != nil;
115 | }
116 |
117 | - (void)loadFailedWithError:(NSError *)error
118 | {
119 | self.loading = NO;
120 | self.cancelled = NO;
121 | [[NSNotificationCenter defaultCenter] postNotificationName:AsyncImageLoadDidFail
122 | object:self.target
123 | userInfo:@{AsyncImageURLKey: self.URL,
124 | AsyncImageErrorKey: error}];
125 | }
126 |
127 | - (void)cacheImage:(UIImage *)image
128 | {
129 | if (!self.cancelled)
130 | {
131 | if (image && self.URL)
132 | {
133 | BOOL storeInCache = YES;
134 | if ([self.URL isFileURL])
135 | {
136 | if ([[[self.URL absoluteURL] path] hasPrefix:[[NSBundle mainBundle] resourcePath]])
137 | {
138 | //do not store in cache
139 | storeInCache = NO;
140 | }
141 | }
142 | if (storeInCache)
143 | {
144 | [self.cache setObject:image forKey:self.URL];
145 | }
146 | }
147 |
148 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
149 | image, AsyncImageImageKey,
150 | self.URL, AsyncImageURLKey,
151 | nil];
152 | if (self.cache)
153 | {
154 | userInfo[AsyncImageCacheKey] = self.cache;
155 | }
156 |
157 | self.loading = NO;
158 | [[NSNotificationCenter defaultCenter] postNotificationName:AsyncImageLoadDidFinish
159 | object:self.target
160 | userInfo:[userInfo copy]];
161 | }
162 | else
163 | {
164 | self.loading = NO;
165 | self.cancelled = NO;
166 | }
167 | }
168 |
169 | - (void)processDataInBackground:(NSData *)data
170 | {
171 | @synchronized ([self class])
172 | {
173 | if (!self.cancelled)
174 | {
175 | UIImage *image = [[UIImage alloc] initWithData:data];
176 | if (image)
177 | {
178 | //redraw to prevent deferred decompression
179 | UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
180 | [image drawAtPoint:CGPointZero];
181 | image = UIGraphicsGetImageFromCurrentImageContext();
182 | UIGraphicsEndImageContext();
183 |
184 | //add to cache (may be cached already but it doesn't matter)
185 | [self performSelectorOnMainThread:@selector(cacheImage:)
186 | withObject:image
187 | waitUntilDone:YES];
188 | }
189 | else
190 | {
191 | @autoreleasepool
192 | {
193 | NSError *error = [NSError errorWithDomain:@"AsyncImageLoader" code:0 userInfo:@{NSLocalizedDescriptionKey: @"Invalid image data"}];
194 | [self performSelectorOnMainThread:@selector(loadFailedWithError:) withObject:error waitUntilDone:YES];
195 | }
196 | }
197 | }
198 | else
199 | {
200 | //clean up
201 | [self performSelectorOnMainThread:@selector(cacheImage:)
202 | withObject:nil
203 | waitUntilDone:YES];
204 | }
205 | }
206 | }
207 |
208 | - (void)connection:(__unused NSURLConnection *)connection didReceiveResponse:(__unused NSURLResponse *)response
209 | {
210 | self.data = [NSMutableData data];
211 | }
212 |
213 | - (void)connection:(__unused NSURLConnection *)connection didReceiveData:(NSData *)data
214 | {
215 | //add data
216 | [self.data appendData:data];
217 | }
218 |
219 | - (void)connectionDidFinishLoading:(__unused NSURLConnection *)connection
220 | {
221 | [self performSelectorInBackground:@selector(processDataInBackground:) withObject:self.data];
222 | self.connection = nil;
223 | self.data = nil;
224 | }
225 |
226 | - (void)connection:(__unused NSURLConnection *)connection didFailWithError:(NSError *)error
227 | {
228 | self.connection = nil;
229 | self.data = nil;
230 | [self loadFailedWithError:error];
231 | }
232 |
233 | - (void)start
234 | {
235 | if (self.loading && !self.cancelled)
236 | {
237 | return;
238 | }
239 |
240 | //begin loading
241 | self.loading = YES;
242 | self.cancelled = NO;
243 |
244 | //check for nil URL
245 | if (self.URL == nil)
246 | {
247 | [self cacheImage:nil];
248 | return;
249 | }
250 |
251 | //check for cached image
252 | UIImage *image = [self cachedImage];
253 | if (image)
254 | {
255 | //add to cache (cached already but it doesn't matter)
256 | [self performSelectorOnMainThread:@selector(cacheImage:)
257 | withObject:image
258 | waitUntilDone:NO];
259 | return;
260 | }
261 |
262 | //begin load
263 | NSURLRequest *request = [NSURLRequest requestWithURL:self.URL
264 | cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
265 | timeoutInterval:[AsyncImageLoader sharedLoader].loadingTimeout];
266 |
267 | self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
268 | [self.connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
269 | [self.connection start];
270 | }
271 |
272 | - (void)cancel
273 | {
274 | self.cancelled = YES;
275 | [self.connection cancel];
276 | self.connection = nil;
277 | self.data = nil;
278 | }
279 |
280 | @end
281 |
282 |
283 | @interface AsyncImageLoader ()
284 |
285 | @property (nonatomic, strong) NSMutableArray *connections;
286 |
287 | @end
288 |
289 |
290 | @implementation AsyncImageLoader
291 |
292 | + (AsyncImageLoader *)sharedLoader
293 | {
294 | static AsyncImageLoader *sharedInstance = nil;
295 | if (sharedInstance == nil)
296 | {
297 | sharedInstance = [(AsyncImageLoader *)[self alloc] init];
298 | }
299 | return sharedInstance;
300 | }
301 |
302 | + (NSCache *)defaultCache
303 | {
304 | static NSCache *sharedCache = nil;
305 | if (sharedCache == nil)
306 | {
307 | sharedCache = [[NSCache alloc] init];
308 | [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(__unused NSNotification *note) {
309 |
310 | [sharedCache removeAllObjects];
311 | }];
312 | }
313 | return sharedCache;
314 | }
315 |
316 | - (AsyncImageLoader *)init
317 | {
318 | if ((self = [super init]))
319 | {
320 | self.cache = [[self class] defaultCache];
321 | _concurrentLoads = 2;
322 | _loadingTimeout = 60.0;
323 | _connections = [[NSMutableArray alloc] init];
324 | [[NSNotificationCenter defaultCenter] addObserver:self
325 | selector:@selector(imageLoaded:)
326 | name:AsyncImageLoadDidFinish
327 | object:nil];
328 | [[NSNotificationCenter defaultCenter] addObserver:self
329 | selector:@selector(imageFailed:)
330 | name:AsyncImageLoadDidFail
331 | object:nil];
332 | }
333 | return self;
334 | }
335 |
336 | - (void)updateQueue
337 | {
338 | //start connections
339 | NSUInteger count = 0;
340 | for (AsyncImageConnection *connection in self.connections)
341 | {
342 | if (![connection isLoading])
343 | {
344 | if ([connection isInCache])
345 | {
346 | [connection start];
347 | }
348 | else if (count < self.concurrentLoads)
349 | {
350 | count ++;
351 | [connection start];
352 | }
353 | }
354 | }
355 | }
356 |
357 | - (void)imageLoaded:(NSNotification *)notification
358 | {
359 | //complete connections for URL
360 | NSURL *URL = (notification.userInfo)[AsyncImageURLKey];
361 | for (NSInteger i = (NSInteger)[self.connections count] - 1; i >= 0; i--)
362 | {
363 | AsyncImageConnection *connection = self.connections[(NSUInteger)i];
364 | if (connection.URL == URL || [connection.URL isEqual:URL])
365 | {
366 | //cancel earlier connections for same target/action
367 | for (NSInteger j = i - 1; j >= 0; j--)
368 | {
369 | AsyncImageConnection *earlier = self.connections[(NSUInteger)j];
370 | if (earlier.target == connection.target &&
371 | earlier.success == connection.success)
372 | {
373 | [earlier cancel];
374 | [self.connections removeObjectAtIndex:(NSUInteger)j];
375 | i--;
376 | }
377 | }
378 |
379 | //cancel connection (in case it's a duplicate)
380 | [connection cancel];
381 |
382 | //perform action
383 | UIImage *image = (notification.userInfo)[AsyncImageImageKey];
384 | ((void (*)(id, SEL, id, id))objc_msgSend)(connection.target, connection.success, image, connection.URL);
385 |
386 | //remove from queue
387 | [self.connections removeObjectAtIndex:(NSUInteger)i];
388 | }
389 | }
390 |
391 | //update the queue
392 | [self updateQueue];
393 | }
394 |
395 | - (void)imageFailed:(NSNotification *)notification
396 | {
397 | //remove connections for URL
398 | NSURL *URL = (notification.userInfo)[AsyncImageURLKey];
399 | for (NSInteger i = (NSInteger)[self.connections count] - 1; i >= 0; i--)
400 | {
401 | AsyncImageConnection *connection = self.connections[(NSUInteger)i];
402 | if ([connection.URL isEqual:URL])
403 | {
404 | //cancel connection (in case it's a duplicate)
405 | [connection cancel];
406 |
407 | //perform failure action
408 | if (connection.failure)
409 | {
410 | NSError *error = (notification.userInfo)[AsyncImageErrorKey];
411 | ((void (*)(id, SEL, id, id))objc_msgSend)(connection.target, connection.failure, error, URL);
412 | }
413 |
414 | //remove from queue
415 | [self.connections removeObjectAtIndex:(NSUInteger)i];
416 | }
417 | }
418 |
419 | //update the queue
420 | [self updateQueue];
421 | }
422 |
423 | - (void)loadImageWithURL:(NSURL *)URL target:(id)target success:(SEL)success failure:(SEL)failure
424 | {
425 | //check cache
426 | UIImage *image = [self.cache objectForKey:URL];
427 | if (image)
428 | {
429 | [self cancelLoadingImagesForTarget:self action:success];
430 | if (success)
431 | {
432 | dispatch_async(dispatch_get_main_queue(), ^(void) {
433 |
434 | ((void (*)(id, SEL, id, id))objc_msgSend)(target, success, image, URL);
435 | });
436 | }
437 | return;
438 | }
439 |
440 | //create new connection
441 | AsyncImageConnection *connection = [[AsyncImageConnection alloc] initWithURL:URL
442 | cache:self.cache
443 | target:target
444 | success:success
445 | failure:failure];
446 | BOOL added = NO;
447 | for (NSUInteger i = 0; i < [self.connections count]; i++)
448 | {
449 | AsyncImageConnection *existingConnection = self.connections[i];
450 | if (!existingConnection.loading)
451 | {
452 | [self.connections insertObject:connection atIndex:i];
453 | added = YES;
454 | break;
455 | }
456 | }
457 | if (!added)
458 | {
459 | [self.connections addObject:connection];
460 | }
461 |
462 | [self updateQueue];
463 | }
464 |
465 | - (void)loadImageWithURL:(NSURL *)URL target:(id)target action:(SEL)action
466 | {
467 | [self loadImageWithURL:URL target:target success:action failure:NULL];
468 | }
469 |
470 | - (void)loadImageWithURL:(NSURL *)URL
471 | {
472 | [self loadImageWithURL:URL target:nil success:NULL failure:NULL];
473 | }
474 |
475 | - (void)cancelLoadingURL:(NSURL *)URL target:(id)target action:(SEL)action
476 | {
477 | for (NSInteger i = (NSInteger)[self.connections count] - 1; i >= 0; i--)
478 | {
479 | AsyncImageConnection *connection = self.connections[(NSUInteger)i];
480 | if ([connection.URL isEqual:URL] && connection.target == target && connection.success == action)
481 | {
482 | [connection cancel];
483 | [self.connections removeObjectAtIndex:(NSUInteger)i];
484 | }
485 | }
486 | }
487 |
488 | - (void)cancelLoadingURL:(NSURL *)URL target:(id)target
489 | {
490 | for (NSInteger i = (NSInteger)[self.connections count] - 1; i >= 0; i--)
491 | {
492 | AsyncImageConnection *connection = self.connections[(NSUInteger)i];
493 | if ([connection.URL isEqual:URL] && connection.target == target)
494 | {
495 | [connection cancel];
496 | [self.connections removeObjectAtIndex:(NSUInteger)i];
497 | }
498 | }
499 | }
500 |
501 | - (void)cancelLoadingURL:(NSURL *)URL
502 | {
503 | for (NSInteger i = (NSInteger)[self.connections count] - 1; i >= 0; i--)
504 | {
505 | AsyncImageConnection *connection = self.connections[(NSUInteger)i];
506 | if ([connection.URL isEqual:URL])
507 | {
508 | [connection cancel];
509 | [self.connections removeObjectAtIndex:(NSUInteger)i];
510 | }
511 | }
512 | }
513 |
514 | - (void)cancelLoadingImagesForTarget:(id)target action:(SEL)action
515 | {
516 | for (NSInteger i = (NSInteger)[self.connections count] - 1; i >= 0; i--)
517 | {
518 | AsyncImageConnection *connection = self.connections[(NSUInteger)i];
519 | if (connection.target == target && connection.success == action)
520 | {
521 | [connection cancel];
522 | }
523 | }
524 | }
525 |
526 | - (void)cancelLoadingImagesForTarget:(id)target
527 | {
528 | for (NSInteger i = (NSInteger)[self.connections count] - 1; i >= 0; i--)
529 | {
530 | AsyncImageConnection *connection = self.connections[(NSUInteger)i];
531 | if (connection.target == target)
532 | {
533 | [connection cancel];
534 | }
535 | }
536 | }
537 |
538 | - (NSURL *)URLForTarget:(id)target action:(SEL)action
539 | {
540 | //return the most recent image URL assigned to the target for the given action
541 | //this is not neccesarily the next image that will be assigned
542 | for (NSInteger i = (NSInteger)[self.connections count] - 1; i >= 0; i--)
543 | {
544 | AsyncImageConnection *connection = self.connections[(NSUInteger)i];
545 | if (connection.target == target && connection.success == action)
546 | {
547 | return connection.URL;
548 | }
549 | }
550 | return nil;
551 | }
552 |
553 | - (NSURL *)URLForTarget:(id)target
554 | {
555 | //return the most recent image URL assigned to the target
556 | //this is not neccesarily the next image that will be assigned
557 | for (NSInteger i = (NSInteger)[self.connections count] - 1; i >= 0; i--)
558 | {
559 | AsyncImageConnection *connection = self.connections[(NSUInteger)i];
560 | if (connection.target == target)
561 | {
562 | return connection.URL;
563 | }
564 | }
565 | return nil;
566 | }
567 |
568 | - (void)dealloc
569 | {
570 | [[NSNotificationCenter defaultCenter] removeObserver:self];
571 | }
572 |
573 | @end
574 |
575 |
576 | @implementation UIImageView(AsyncImageView)
577 |
578 | - (void)setImageURL:(NSURL *)imageURL
579 | {
580 | [[AsyncImageLoader sharedLoader] loadImageWithURL:imageURL target:self action:@selector(setImage:)];
581 | }
582 |
583 | - (NSURL *)imageURL
584 | {
585 | return [[AsyncImageLoader sharedLoader] URLForTarget:self action:@selector(setImage:)];
586 | }
587 |
588 | @end
589 |
590 |
591 | @interface AsyncImageView ()
592 |
593 | @property (nonatomic, strong) UIActivityIndicatorView *activityView;
594 |
595 | @end
596 |
597 |
598 | @implementation AsyncImageView
599 |
600 | - (void)setUp
601 | {
602 | self.showActivityIndicator = (self.image == nil);
603 | self.activityIndicatorStyle = UIActivityIndicatorViewStyleGray;
604 | self.crossfadeDuration = 0.4;
605 | }
606 |
607 | - (id)initWithFrame:(CGRect)frame
608 | {
609 | if ((self = [super initWithFrame:frame]))
610 | {
611 | [self setUp];
612 | }
613 | return self;
614 | }
615 |
616 | - (id)initWithCoder:(NSCoder *)aDecoder
617 | {
618 | if ((self = [super initWithCoder:aDecoder]))
619 | {
620 | [self setUp];
621 | }
622 | return self;
623 | }
624 |
625 | - (void)setImageURL:(NSURL *)imageURL
626 | {
627 | UIImage *image = [[AsyncImageLoader sharedLoader].cache objectForKey:imageURL];
628 | if (image)
629 | {
630 | self.image = image;
631 | return;
632 | }
633 | super.imageURL = imageURL;
634 | if (self.showActivityIndicator && !self.image && imageURL)
635 | {
636 | if (self.activityView == nil)
637 | {
638 | self.activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorStyle];
639 | self.activityView.hidesWhenStopped = YES;
640 | self.activityView.center = CGPointMake(self.bounds.size.width / 2.0f, self.bounds.size.height / 2.0f);
641 | self.activityView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
642 | [self addSubview:self.activityView];
643 | }
644 | [self.activityView startAnimating];
645 | }
646 | }
647 |
648 | - (void)setActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style
649 | {
650 | _activityIndicatorStyle = style;
651 | [self.activityView removeFromSuperview];
652 | self.activityView = nil;
653 | }
654 |
655 | - (void)setImage:(UIImage *)image
656 | {
657 | if (image != self.image && self.crossfadeDuration)
658 | {
659 | //jump through a few hoops to avoid QuartzCore framework dependency
660 | CAAnimation *animation = [NSClassFromString(@"CATransition") animation];
661 | [animation setValue:@"kCATransitionFade" forKey:@"type"];
662 | animation.duration = self.crossfadeDuration;
663 | [self.layer addAnimation:animation forKey:nil];
664 | }
665 | super.image = image;
666 | [self.activityView stopAnimating];
667 | }
668 |
669 | - (void)dealloc
670 | {
671 | [[AsyncImageLoader sharedLoader] cancelLoadingURL:self.imageURL target:self];
672 | }
673 |
674 | @end
675 |
--------------------------------------------------------------------------------
/Classes/ComCitytelecomTiparallaxheaderModule.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Your Copyright Here
3 | *
4 | * Appcelerator Titanium is Copyright (c) 2009-2010 by Appcelerator, Inc.
5 | * and licensed under the Apache Public License (version 2)
6 | */
7 | #import "TiModule.h"
8 |
9 | @interface ComCitytelecomTiparallaxheaderModule : TiModule
10 | {
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Classes/ComCitytelecomTiparallaxheaderModule.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Your Copyright Here
3 | *
4 | * Appcelerator Titanium is Copyright (c) 2009-2010 by Appcelerator, Inc.
5 | * and licensed under the Apache Public License (version 2)
6 | */
7 | #import "ComCitytelecomTiparallaxheaderModule.h"
8 | #import "TiBase.h"
9 | #import "TiHost.h"
10 | #import "TiUtils.h"
11 | #import "TiUIListView+ParallaxHeader.h"
12 | #import "UITableView+HeaderSectionPosition.h"
13 |
14 | @implementation ComCitytelecomTiparallaxheaderModule
15 |
16 | #pragma mark Internal
17 |
18 | // this is generated for your module, please do not change it
19 | -(id)moduleGUID
20 | {
21 | return @"d9d5b1e0-b0fc-4814-bb86-41dc12db6808";
22 | }
23 |
24 | // this is generated for your module, please do not change it
25 | -(NSString*)moduleId
26 | {
27 | return @"com.citytelecom.tiparallaxheader";
28 | }
29 |
30 | #pragma mark Lifecycle
31 |
32 | -(void)startup
33 | {
34 | // this method is called when the module is first loaded
35 | // you *must* call the superclass
36 | [super startup];
37 |
38 | //swizzle out the uitableview for the insets
39 | [UITableView swizzle];
40 |
41 | //swizzle the listview
42 | [TiUIListView swizzle];
43 |
44 | NSLog(@"[INFO] %@ loaded",self);
45 | }
46 |
47 | -(void)shutdown:(id)sender
48 | {
49 | // this method is called when the module is being unloaded
50 | // typically this is during shutdown. make sure you don't do too
51 | // much processing here or the app will be quit forceably
52 |
53 | // you *must* call the superclass
54 | [super shutdown:sender];
55 | }
56 |
57 | #pragma mark Cleanup
58 |
59 | -(void)dealloc
60 | {
61 | // release any resources that have been retained by the module
62 | [super dealloc];
63 | }
64 |
65 | #pragma mark Internal Memory Management
66 |
67 | -(void)didReceiveMemoryWarning:(NSNotification*)notification
68 | {
69 | // optionally release any resources that can be dynamically
70 | // reloaded once memory is available - such as caches
71 | [super didReceiveMemoryWarning:notification];
72 | }
73 |
74 | #pragma mark Listener Notifications
75 |
76 | -(void)_listenerAdded:(NSString *)type count:(int)count
77 | {
78 | if (count == 1 && [type isEqualToString:@"my_event"])
79 | {
80 | // the first (of potentially many) listener is being added
81 | // for event named 'my_event'
82 | }
83 | }
84 |
85 | -(void)_listenerRemoved:(NSString *)type count:(int)count
86 | {
87 | if (count == 0 && [type isEqualToString:@"my_event"])
88 | {
89 | // the last listener called for event named 'my_event' has
90 | // been removed, we can optionally clean up any resources
91 | // since no body is listening at this point for that event
92 | }
93 | }
94 |
95 | #pragma Public APIs
96 |
97 | -(id)example:(id)args
98 | {
99 | // example method
100 | return @"hello world";
101 | }
102 |
103 | -(id)exampleProp
104 | {
105 | // example property getter
106 | return @"hello world";
107 | }
108 |
109 | -(void)setExampleProp:(id)value
110 | {
111 | // example property setter
112 | }
113 |
114 | @end
115 |
--------------------------------------------------------------------------------
/Classes/ComCitytelecomTiparallaxheaderModuleAssets.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This is a generated file. Do not edit or your changes will be lost
3 | */
4 |
5 | @interface ComCitytelecomTiparallaxheaderModuleAssets : NSObject
6 | {
7 | }
8 | - (NSData*) moduleAsset;
9 | - (NSData*) resolveModuleAsset:(NSString*)path;
10 |
11 | @end
12 |
--------------------------------------------------------------------------------
/Classes/ComCitytelecomTiparallaxheaderModuleAssets.m:
--------------------------------------------------------------------------------
1 | /**
2 | * This is a generated file. Do not edit or your changes will be lost
3 | */
4 | #import "ComCitytelecomTiparallaxheaderModuleAssets.h"
5 |
6 | extern NSData* filterDataInRange(NSData* thedata, NSRange range);
7 |
8 | @implementation ComCitytelecomTiparallaxheaderModuleAssets
9 |
10 | - (NSData*) moduleAsset
11 | {
12 | //##TI_AUTOGEN_BEGIN asset
13 |
14 | static UInt8 data[] = {
15 | 0xa0,0x50,0xfa,0xda,0xff,0xf0,0x21,0x77,0xeb,0x69,0x65,0x61,0xeb,0x2a,0x5b,0x5b,0x2f,0x06,0x60,0xdc
16 | ,0x4f,0x34,0xbf,0x49,0x00,0x12,0x57,0x6a,0x40,0x0a,0x0e,0x9c,0xf9,0x08,0xbb,0xb5,0x2b,0x86,0x45,0x85
17 | ,0xdd,0x68,0x75,0xb7,0x00,0x12,0x63,0x98,0x82,0xa7,0xf8,0x15,0xb3,0xcf,0x20,0x8c,0x98,0xa7,0x14,0x27
18 | ,0x53,0x96,0xc1,0xb4 };
19 | static NSRange ranges[] = {
20 | {0,32}
21 | };
22 | static NSDictionary *map = nil;
23 | if (map == nil) {
24 | map = [[NSDictionary alloc] initWithObjectsAndKeys:
25 | [NSNumber numberWithInteger:0], @"com_citytelecom_tiparallaxheader_js",
26 | nil];
27 | }
28 |
29 |
30 | return filterDataInRange([NSData dataWithBytesNoCopy:data length:sizeof(data) freeWhenDone:NO], ranges[0]);
31 | //##TI_AUTOGEN_END asset
32 | }
33 |
34 | - (NSData*) resolveModuleAsset:(NSString*)path
35 | {
36 | //##TI_AUTOGEN_BEGIN resolve_asset
37 |
38 | static UInt8 data[] = {
39 | 0x79,0xd0,0x56,0x08,0x95,0xbd,0xa3,0xa2,0x63,0x87,0xe2,0x38,0x47,0xf9,0x41,0x2b,0x0e,0x71,0xc6,0x71
40 | ,0xa8,0xc7,0x1e,0x6e,0x83,0xc7,0xce,0xb2,0x4b,0x00,0xa8,0xe2,0x39,0x2e,0xb2,0xc0,0x71,0xbd,0xdd,0x46
41 | ,0x4a,0x8f,0x44,0x72,0xfb,0x41,0x8a,0x72,0x36,0x61,0x0d,0xad,0x0f,0xc5,0x4f,0x42,0x3f,0x58,0xb3,0x5f
42 | ,0x20,0x40,0xb0,0x58 };
43 | static NSRange ranges[] = {
44 | {0,32}
45 | };
46 | static NSDictionary *map = nil;
47 | if (map == nil) {
48 | map = [[NSDictionary alloc] initWithObjectsAndKeys:
49 | [NSNumber numberWithInteger:0], @"com_citytelecom_tiparallaxheader_js",
50 | nil];
51 | }
52 |
53 |
54 | NSNumber *index = [map objectForKey:path];
55 | if (index == nil) {
56 | return nil;
57 | }
58 | return filterDataInRange([NSData dataWithBytesNoCopy:data length:sizeof(data) freeWhenDone:NO], ranges[index.integerValue]);
59 | //##TI_AUTOGEN_END resolve_asset
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/Classes/NSObject+JRSwizzle.h:
--------------------------------------------------------------------------------
1 | // JRSwizzle.h semver:1.0
2 | // Copyright (c) 2007-2011 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
3 | // Some rights reserved: http://opensource.org/licenses/MIT
4 | // https://github.com/rentzsch/jrswizzle
5 |
6 | #import
7 |
8 | @interface NSObject (JRSwizzle)
9 |
10 | + (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_;
11 | + (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Classes/NSObject+JRSwizzle.m:
--------------------------------------------------------------------------------
1 | // JRSwizzle.m semver:1.0
2 | // Copyright (c) 2007-2011 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
3 | // Some rights reserved: http://opensource.org/licenses/MIT
4 | // https://github.com/rentzsch/jrswizzle
5 |
6 | #import "NSObject+JRSwizzle.h"
7 |
8 | #if TARGET_OS_IPHONE
9 | #import
10 | #import
11 | #else
12 | #import
13 | #endif
14 |
15 | #define SetNSErrorFor(FUNC, ERROR_VAR, FORMAT,...) \
16 | if (ERROR_VAR) { \
17 | NSString *errStr = [NSString stringWithFormat:@"%s: " FORMAT,FUNC,##__VA_ARGS__]; \
18 | *ERROR_VAR = [NSError errorWithDomain:@"NSCocoaErrorDomain" \
19 | code:-1 \
20 | userInfo:[NSDictionary dictionaryWithObject:errStr forKey:NSLocalizedDescriptionKey]]; \
21 | }
22 | #define SetNSError(ERROR_VAR, FORMAT,...) SetNSErrorFor(__func__, ERROR_VAR, FORMAT, ##__VA_ARGS__)
23 |
24 | #if OBJC_API_VERSION >= 2
25 | #define GetClass(obj) object_getClass(obj)
26 | #else
27 | #define GetClass(obj) (obj ? obj->isa : Nil)
28 | #endif
29 |
30 | @implementation NSObject (JRSwizzle)
31 |
32 | + (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_ {
33 | #if OBJC_API_VERSION >= 2
34 | Method origMethod = class_getInstanceMethod(self, origSel_);
35 | if (!origMethod) {
36 | #if TARGET_OS_IPHONE
37 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self class]);
38 | #else
39 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]);
40 | #endif
41 | return NO;
42 | }
43 |
44 | Method altMethod = class_getInstanceMethod(self, altSel_);
45 | if (!altMethod) {
46 | #if TARGET_OS_IPHONE
47 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self class]);
48 | #else
49 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]);
50 | #endif
51 | return NO;
52 | }
53 |
54 | class_addMethod(self,
55 | origSel_,
56 | class_getMethodImplementation(self, origSel_),
57 | method_getTypeEncoding(origMethod));
58 | class_addMethod(self,
59 | altSel_,
60 | class_getMethodImplementation(self, altSel_),
61 | method_getTypeEncoding(altMethod));
62 |
63 | method_exchangeImplementations(class_getInstanceMethod(self, origSel_), class_getInstanceMethod(self, altSel_));
64 | return YES;
65 | #else
66 | // Scan for non-inherited methods.
67 | Method directOriginalMethod = NULL, directAlternateMethod = NULL;
68 |
69 | void *iterator = NULL;
70 | struct objc_method_list *mlist = class_nextMethodList(self, &iterator);
71 | while (mlist) {
72 | int method_index = 0;
73 | for (; method_index < mlist->method_count; method_index++) {
74 | if (mlist->method_list[method_index].method_name == origSel_) {
75 | assert(!directOriginalMethod);
76 | directOriginalMethod = &mlist->method_list[method_index];
77 | }
78 | if (mlist->method_list[method_index].method_name == altSel_) {
79 | assert(!directAlternateMethod);
80 | directAlternateMethod = &mlist->method_list[method_index];
81 | }
82 | }
83 | mlist = class_nextMethodList(self, &iterator);
84 | }
85 |
86 | // If either method is inherited, copy it up to the target class to make it non-inherited.
87 | if (!directOriginalMethod || !directAlternateMethod) {
88 | Method inheritedOriginalMethod = NULL, inheritedAlternateMethod = NULL;
89 | if (!directOriginalMethod) {
90 | inheritedOriginalMethod = class_getInstanceMethod(self, origSel_);
91 | if (!inheritedOriginalMethod) {
92 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]);
93 | return NO;
94 | }
95 | }
96 | if (!directAlternateMethod) {
97 | inheritedAlternateMethod = class_getInstanceMethod(self, altSel_);
98 | if (!inheritedAlternateMethod) {
99 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]);
100 | return NO;
101 | }
102 | }
103 |
104 | int hoisted_method_count = !directOriginalMethod && !directAlternateMethod ? 2 : 1;
105 | struct objc_method_list *hoisted_method_list = malloc(sizeof(struct objc_method_list) + (sizeof(struct objc_method)*(hoisted_method_count-1)));
106 | hoisted_method_list->obsolete = NULL; // soothe valgrind - apparently ObjC runtime accesses this value and it shows as uninitialized in valgrind
107 | hoisted_method_list->method_count = hoisted_method_count;
108 | Method hoisted_method = hoisted_method_list->method_list;
109 |
110 | if (!directOriginalMethod) {
111 | bcopy(inheritedOriginalMethod, hoisted_method, sizeof(struct objc_method));
112 | directOriginalMethod = hoisted_method++;
113 | }
114 | if (!directAlternateMethod) {
115 | bcopy(inheritedAlternateMethod, hoisted_method, sizeof(struct objc_method));
116 | directAlternateMethod = hoisted_method;
117 | }
118 | class_addMethods(self, hoisted_method_list);
119 | }
120 |
121 | // Swizzle.
122 | IMP temp = directOriginalMethod->method_imp;
123 | directOriginalMethod->method_imp = directAlternateMethod->method_imp;
124 | directAlternateMethod->method_imp = temp;
125 |
126 | return YES;
127 | #endif
128 | }
129 |
130 | + (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_ {
131 | return [GetClass((id)self) jr_swizzleMethod:origSel_ withMethod:altSel_ error:error_];
132 | }
133 |
134 | @end
--------------------------------------------------------------------------------
/Classes/TiUIListView+ParallaxHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // TiUIListView+ParallaxHeader.h
3 | // TiParallaxHeader
4 | //
5 | // Created by James Chow on 17/04/2014.
6 | //
7 | //
8 |
9 | #import "TiUIView.h"
10 | #import "TiUIListViewProxy.h"
11 | #import "TiUIListView.h"
12 | #import "TiViewProxy.h"
13 |
14 | @interface TiUIListView (ParallaxHeader)
15 |
16 | @property (nonatomic, retain) UIImage * currentImage;
17 | @property (nonatomic, retain) TiViewProxy * currentHeaderView;
18 |
19 | + (void) swizzle;
20 |
21 | -(void)addParallaxWithView:(TiViewProxy *)headerview withHeight: (CGFloat) height;
22 | -(void)addParallaxWithImage:(NSString *)url forHeight: (CGFloat) height;
23 | -(void)setSectionHeaderInset:(CGFloat) height;
24 | -(void)setFadeoutOverHeight:(NSNumber*) height;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/Classes/TiUIListView+ParallaxHeader.m:
--------------------------------------------------------------------------------
1 | //
2 | // TiUIListView+ParallaxHeader.m
3 | // TiParallaxHeader
4 | //
5 | // Created by James Chow on 17/04/2014.
6 | //
7 | //
8 |
9 | #import "TiUIListView+ParallaxHeader.h"
10 | #import "TiUtils.h"
11 | #import "TiUIViewProxy.h"
12 | #import "UIScrollView+APParallaxHeader.h"
13 | #import "UITableView+HeaderSectionPosition.h"
14 | #import "NSObject+JRSwizzle.h"
15 | #import
16 |
17 | @implementation TiUIListView (ParallaxHeader)
18 |
19 | + (void) swizzle
20 | {
21 | NSError *error = nil;
22 | [TiUIListView jr_swizzleMethod:@selector(tableView:viewForHeaderInSection:) withMethod:@selector(swizzle_tableView:viewForHeaderInSection:) error:&error];
23 |
24 | if (error != nil) {
25 | NSLog(@"[ERROR] %@", [error localizedDescription]);
26 | }
27 | }
28 |
29 |
30 | -(void)addParallaxWithView:(TiViewProxy *)headerview withHeight: (CGFloat) height
31 | {
32 | self.currentHeaderView = headerview;
33 |
34 | [self.tableView addParallaxWithView: headerview andHeight:height];
35 | }
36 |
37 | -(void)addParallaxWithImage:(NSString *)url forHeight:(CGFloat)height
38 | {
39 | [self.tableView addParallaxWithImage:url andHeight:height];
40 | }
41 |
42 | -(void)setSectionHeaderInset:(CGFloat) height
43 | {
44 | [self.tableView setHeaderViewInsets:UIEdgeInsetsMake(height, 0, 0, 0)];
45 | }
46 |
47 | -(void)setFadeoutOverHeight:(NSNumber*) height
48 | {
49 | [self.tableView setFadeoutOverHeight:height];
50 | }
51 |
52 | -(void)setCurrentImage:(UIImage *)_currentImage
53 | {
54 | objc_setAssociatedObject(self, @selector(currentImage), _currentImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
55 | };
56 |
57 | -(UIImage*)currentImage
58 | {
59 | return objc_getAssociatedObject(self, @selector(currentImage));
60 | }
61 |
62 | -(void)setCurrentHeaderView:(TiViewProxy *)_currentHeaderView
63 | {
64 | objc_setAssociatedObject(self, @selector(currentHeaderView), _currentHeaderView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
65 | };
66 |
67 | -(TiViewProxy*)currentHeaderView
68 | {
69 | return objc_getAssociatedObject(self, @selector(currentHeaderView));
70 | }
71 |
72 | - (UIView *)swizzle_tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
73 | {
74 |
75 | [TiUIListView jr_swizzleMethod:@selector(tableView:viewForHeaderInSection:) withMethod:@selector(swizzle_tableView:viewForHeaderInSection:) error:nil];
76 |
77 | //using a plain UI view we need to use tags
78 | //http://stackoverflow.com/questions/20188049/uitableview-headerviewforsection-returns-null
79 |
80 | UIView * sectionHeView = [self tableView:tableView viewForHeaderInSection:section];
81 | [sectionHeView setTag:100+section];
82 |
83 | [TiUIListView jr_swizzleMethod:@selector(tableView:viewForHeaderInSection:) withMethod:@selector(swizzle_tableView:viewForHeaderInSection:) error:nil];
84 |
85 | return sectionHeView;
86 | }
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/Classes/TiUIListViewProxy+ProxyParallaxHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // TiUIListViewProxy+ProxyParallaxHeader.h
3 | // TiParallaxHeader
4 | //
5 | // Created by James Chow on 17/04/2014.
6 | //
7 | //
8 |
9 | #import "TiUIListViewProxy.h"
10 | #import "TiUIViewProxy.h"
11 | #import "TiProxy.h"
12 | #import
13 |
14 | @interface TiUIListViewProxy (ProxyParallaxHeader)
15 |
16 | @property (nonatomic, retain) UIImage * currentImage;
17 |
18 | -(void)addParallaxWithView:(id)args;
19 | -(void)addParallaxWithImage:(id)args;
20 | -(void)setSectionHeaderInset:(id)args;
21 | -(void)setFadeoutOverHeight:(id)args;
22 | @end
23 |
--------------------------------------------------------------------------------
/Classes/TiUIListViewProxy+ProxyParallaxHeader.m:
--------------------------------------------------------------------------------
1 | //
2 | // TiUIListViewProxy+ProxyParallaxHeader.m
3 | // TiParallaxHeader
4 | //
5 | // Created by James Chow on 17/04/2014.
6 | //
7 | //
8 |
9 | #import "TiUIListViewProxy+ProxyParallaxHeader.h"
10 | #import "TiUIListView+ParallaxHeader.h"
11 | #import "TiUIListViewProxy.h"
12 | #import "TiProxy.h"
13 | #import
14 |
15 | @implementation TiUIListViewProxy (ProxyParallaxHeader)
16 |
17 |
18 | -(void)setCurrentImage:(UIImage *)_currentImage
19 | {
20 | objc_setAssociatedObject(self, @selector(currentImage), _currentImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
21 | };
22 |
23 | -(UIImage*)currentImage
24 | {
25 | return objc_getAssociatedObject(self, @selector(currentImage));
26 | }
27 |
28 | -(void)addParallaxWithView:(id)args
29 | {
30 | ENSURE_UI_THREAD_1_ARG(args);
31 |
32 | TiViewProxy *headerView = nil;
33 | ENSURE_ARG_AT_INDEX(headerView,args,0,TiViewProxy);
34 | NSNumber *height = nil;
35 |
36 | ENSURE_ARG_AT_INDEX(height,args,1,NSNumber);
37 |
38 | TiUIListView *convert = (TiUIListView*) self.view;
39 | [convert addParallaxWithView:headerView withHeight:[height floatValue]];
40 | }
41 |
42 | -(void)addParallaxWithImage:(id)args
43 | {
44 | ENSURE_UI_THREAD_1_ARG(args);
45 |
46 | NSString * url = nil;
47 | ENSURE_ARG_AT_INDEX(url,args,0,NSString);
48 | NSNumber * height = nil;
49 | ENSURE_ARG_AT_INDEX(height,args,1,NSNumber);
50 |
51 | TiUIListView *convert = (TiUIListView*) self.view;
52 |
53 | [convert addParallaxWithImage:url forHeight:[height floatValue]];
54 | }
55 |
56 | -(void)setSectionHeaderInset:(id)args
57 | {
58 | ENSURE_UI_THREAD_1_ARG(args);
59 | ENSURE_SINGLE_ARG(args, NSNumber);
60 |
61 | CGFloat height = [(NSNumber*)args floatValue];
62 |
63 | TiUIListView *convert = (TiUIListView*) self.view;
64 | [convert setSectionHeaderInset:height];
65 | }
66 |
67 | -(void)setFadeoutOverHeight:(id)args
68 | {
69 | ENSURE_UI_THREAD_1_ARG(args);
70 |
71 | ENSURE_SINGLE_ARG(args, NSNumber);
72 |
73 | TiUIListView *convert = (TiUIListView*) self.view;
74 |
75 | [convert setFadeoutOverHeight:(NSNumber*)args];
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/Classes/UIScrollView+APParallaxHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIScrollView+APParallaxHeader.h
3 | //
4 | // Created by Mathias Amnell on 2013-04-12.
5 | // Copyright (c) 2013 Apping AB. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | @class APParallaxView;
11 | @class APParallaxShadowView;
12 |
13 | @interface UIScrollView (APParallaxHeader)
14 |
15 | - (void)addParallaxWithImage:(NSString *)url andHeight:(CGFloat)height;
16 | - (void)addParallaxWithView:(TiViewProxy*)view andHeight:(CGFloat)height;
17 | - (void)setFadeoutOverHeight:(NSNumber*)height;
18 |
19 | @property (nonatomic, strong, readonly) APParallaxView *parallaxView;
20 | @property (nonatomic, assign) BOOL showsParallax;
21 |
22 | @end
23 |
24 | enum {
25 | APParallaxTrackingActive = 0,
26 | APParallaxTrackingInactive
27 | };
28 |
29 | typedef NSUInteger APParallaxTrackingState;
30 |
31 | @interface APParallaxView : UIView
32 |
33 | @property (nonatomic, readonly) APParallaxTrackingState state;
34 | @property (nonatomic, strong) UIImageView *imageView;
35 | @property (nonatomic, strong) UIView *currentSubView;
36 | @property (nonatomic, strong) APParallaxShadowView *shadowView;
37 | @property (nonatomic, strong) NSNumber *fadeoutOverHeight;
38 |
39 | @end
40 |
41 | @interface APParallaxShadowView : UIView
42 |
43 | @end
--------------------------------------------------------------------------------
/Classes/UIScrollView+APParallaxHeader.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIScrollView+APParallaxHeader.m
3 | //
4 | // Created by Mathias Amnell on 2013-04-12.
5 | // Copyright (c) 2013 Apping AB. All rights reserved.
6 | //
7 |
8 | #import "UIScrollView+APParallaxHeader.h"
9 | #import "AsyncImageView.h"
10 |
11 | #import
12 |
13 | @interface APParallaxView ()
14 |
15 | @property (nonatomic, readwrite) APParallaxTrackingState state;
16 |
17 | @property (nonatomic) UIScrollView *scrollView;
18 | @property (nonatomic, readwrite) CGFloat originalTopInset;
19 | @property (nonatomic) CGFloat parallaxHeight;
20 |
21 | @property(nonatomic, assign) BOOL isObserving;
22 |
23 | @end
24 |
25 |
26 |
27 | #pragma mark - UIScrollView (APParallaxHeader)
28 | #import
29 |
30 | static char UIScrollViewParallaxView;
31 |
32 | @implementation UIScrollView (APParallaxHeader)
33 |
34 | - (void)addParallaxWithImage:(NSString *)url andHeight:(CGFloat)height {
35 | if(self.parallaxView) {
36 | if(self.parallaxView.currentSubView) [self.parallaxView.currentSubView removeFromSuperview];
37 | [self.parallaxView.imageView setImageURL:[NSURL URLWithString:url]];
38 | }
39 | else
40 | {
41 | APParallaxView *view = [[APParallaxView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, height)];
42 | [view setClipsToBounds:YES];
43 | [view.imageView setImageURL:[NSURL URLWithString:url]];
44 |
45 | view.scrollView = self;
46 | view.parallaxHeight = height;
47 | [self addSubview:view];
48 |
49 | view.originalTopInset = self.contentInset.top;
50 |
51 | UIEdgeInsets newInset = self.contentInset;
52 | newInset.top = height;
53 | self.contentInset = newInset;
54 |
55 | self.parallaxView = view;
56 | self.showsParallax = YES;
57 | }
58 | }
59 |
60 | - (void)setFadeoutOverHeight:(NSNumber*)height {
61 | self.parallaxView.fadeoutOverHeight = height;
62 | }
63 |
64 | - (void)addParallaxWithView:(TiViewProxy*)proxyView andHeight:(CGFloat)height {
65 | if(self.parallaxView) {
66 | [self.parallaxView.currentSubView removeFromSuperview];
67 | //[proxyView.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
68 | [self.parallaxView addSubview:proxyView.view];
69 | }
70 | else
71 | {
72 | APParallaxView *parallaxView = [[APParallaxView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(proxyView.view.frame), height)];
73 | [parallaxView setClipsToBounds:YES];
74 | //[proxyView.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
75 | [parallaxView addSubview:proxyView.view];
76 |
77 | parallaxView.scrollView = self;
78 | parallaxView.parallaxHeight = height;
79 | [self addSubview:parallaxView];
80 |
81 | parallaxView.originalTopInset = self.contentInset.top;
82 |
83 | UIEdgeInsets newInset = self.contentInset;
84 | newInset.top = height;
85 | self.contentInset = newInset;
86 |
87 | self.parallaxView = parallaxView;
88 | self.showsParallax = YES;
89 | }
90 | }
91 |
92 | - (void)setParallaxView:(APParallaxView *)parallaxView {
93 | objc_setAssociatedObject(self, &UIScrollViewParallaxView,
94 | parallaxView,
95 | OBJC_ASSOCIATION_ASSIGN);
96 | }
97 |
98 | - (APParallaxView *)parallaxView {
99 | return objc_getAssociatedObject(self, &UIScrollViewParallaxView);
100 | }
101 |
102 | - (void)setShowsParallax:(BOOL)showsParallax {
103 | self.parallaxView.hidden = !showsParallax;
104 |
105 | if(!showsParallax) {
106 | if (self.parallaxView.isObserving) {
107 | [self removeObserver:self.parallaxView forKeyPath:@"contentOffset"];
108 | [self removeObserver:self.parallaxView forKeyPath:@"frame"];
109 | self.parallaxView.isObserving = NO;
110 | }
111 | }
112 | else {
113 | if (!self.parallaxView.isObserving) {
114 | [self addObserver:self.parallaxView forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
115 | [self addObserver:self.parallaxView forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
116 | self.parallaxView.isObserving = YES;
117 | }
118 | }
119 | }
120 |
121 | - (BOOL)showsParallax {
122 | return !self.parallaxView.hidden;
123 | }
124 |
125 | @end
126 |
127 | #pragma mark - ShadowLayer
128 |
129 | @implementation APParallaxShadowView
130 | - (id)initWithFrame:(CGRect)frame
131 | {
132 | self = [super initWithFrame:frame];
133 | if (self) {
134 | [self setOpaque:NO];
135 | }
136 | return self;
137 | }
138 |
139 | - (void)drawRect:(CGRect)rect
140 | {
141 | [super drawRect:rect];
142 |
143 | //// General Declarations
144 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
145 | CGContextRef context = UIGraphicsGetCurrentContext();
146 |
147 |
148 | //// Gradient Declarations
149 | NSArray* gradient3Colors = [NSArray arrayWithObjects:
150 | (id)[UIColor colorWithWhite:0 alpha:0.3].CGColor,
151 | (id)[UIColor clearColor].CGColor, nil];
152 | CGFloat gradient3Locations[] = {0, 1};
153 | CGGradientRef gradient3 = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradient3Colors, gradient3Locations);
154 |
155 | //// Rectangle Drawing
156 | UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRect: CGRectMake(0, 0, CGRectGetWidth(rect), 8)];
157 | CGContextSaveGState(context);
158 | [rectanglePath addClip];
159 | CGContextDrawLinearGradient(context, gradient3, CGPointMake(0, CGRectGetHeight(rect)), CGPointMake(0, 0), 0);
160 | CGContextRestoreGState(context);
161 |
162 |
163 | //// Cleanup
164 | CGGradientRelease(gradient3);
165 | CGColorSpaceRelease(colorSpace);
166 |
167 | }
168 |
169 | @end
170 |
171 | #pragma mark - APParallaxView
172 |
173 | @implementation APParallaxView
174 |
175 | - (id)initWithFrame:(CGRect)frame {
176 | if(self = [super initWithFrame:frame]) {
177 |
178 | // default styling values
179 | [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
180 | [self setState:APParallaxTrackingActive];
181 | [self setAutoresizesSubviews:YES];
182 |
183 | self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame))];
184 | [self.imageView setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
185 | [self.imageView setContentMode:UIViewContentModeScaleAspectFill];
186 | [self.imageView setClipsToBounds:YES];
187 | [self addSubview:self.imageView];
188 |
189 | self.shadowView = [[APParallaxShadowView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(frame)-8, CGRectGetWidth(frame), 8)];
190 | [self.shadowView setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin];
191 | [self addSubview:self.shadowView];
192 |
193 | self.fadeoutOverHeight = nil;
194 | self.currentSubView = nil;
195 | }
196 |
197 | return self;
198 | }
199 |
200 | - (void)willMoveToSuperview:(UIView *)newSuperview {
201 | if (self.superview && newSuperview == nil) {
202 | UIScrollView *scrollView = (UIScrollView *)self.superview;
203 | if (scrollView.showsParallax) {
204 | if (self.isObserving) {
205 | //If enter this branch, it is the moment just before "APParallaxView's dealloc", so remove observer here
206 | [scrollView removeObserver:self forKeyPath:@"contentOffset"];
207 | [scrollView removeObserver:self forKeyPath:@"frame"];
208 | self.isObserving = NO;
209 | }
210 | }
211 | }
212 | }
213 |
214 | - (void)addSubview:(UIView *)view
215 | {
216 | [super addSubview:view];
217 | self.currentSubView = view;
218 | }
219 |
220 | #pragma mark - Observing
221 |
222 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
223 | if([keyPath isEqualToString:@"contentOffset"])
224 | [self scrollViewDidScroll:[[change valueForKey:NSKeyValueChangeNewKey] CGPointValue]];
225 | else if([keyPath isEqualToString:@"frame"])
226 | [self layoutSubviews];
227 | }
228 |
229 | - (void)scrollViewDidScroll:(CGPoint)contentOffset {
230 | // We do not want to track when the parallax view is hidden
231 | if (contentOffset.y > 0) {
232 | [self setState:APParallaxTrackingInactive];
233 | } else {
234 | [self setState:APParallaxTrackingActive];
235 | }
236 |
237 | if(self.state == APParallaxTrackingActive) {
238 | CGFloat yOffset = contentOffset.y*-1;
239 |
240 | [self setFrame:CGRectMake(0, contentOffset.y, CGRectGetWidth(self.frame), yOffset)];
241 |
242 | //size the TiView
243 | if (self.currentSubView != nil)
244 | {
245 | [self.currentSubView setFrame:CGRectMake(0, 0, CGRectGetWidth(self.frame), yOffset)];
246 | }
247 |
248 | //Fade out TiView
249 | if (self.fadeoutOverHeight != nil)
250 | {
251 | CGFloat diff = 1;
252 | CGFloat fadeout = [self.fadeoutOverHeight floatValue];
253 | if (yOffset < self.parallaxHeight)
254 | {
255 | diff = 1;
256 | }
257 | else if ( yOffset >= (self.parallaxHeight + fadeout) )
258 | {
259 | diff = 0;
260 | }
261 | else if (yOffset < (self.parallaxHeight + fadeout) )
262 | {
263 | diff = 1-((yOffset - self.parallaxHeight)/fadeout);
264 | }
265 | [self.currentSubView setAlpha:diff];
266 | }
267 | }
268 | }
269 |
270 | @end
--------------------------------------------------------------------------------
/Classes/UITableView+HeaderSectionPosition.h:
--------------------------------------------------------------------------------
1 | //
2 | // UITableView+HeaderSectionPosition.h
3 | // Category to extend UITableView, which TiUIListView uses
4 | //
5 | // Created by James Chow on 11/04/2014.
6 | //
7 | //
8 |
9 | #import
10 |
11 | @interface UITableView (HeaderSectionPosition)
12 |
13 | @property (nonatomic, assign) UIEdgeInsets headerViewInsets;
14 |
15 | + (void) swizzle;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Classes/UITableView+HeaderSectionPosition.m:
--------------------------------------------------------------------------------
1 | //
2 | // UITableView+HeaderSectionPosition.m
3 | // Category to extend UITableView, which TiUIListView uses
4 | //
5 | // Created by James Chow on 11/04/2014.
6 | // http://b2cloud.com.au/tutorial/uitableview-section-header-positions/
7 | //
8 |
9 | #import "UITableView+HeaderSectionPosition.h"
10 | #import "NSObject+JRSwizzle.h"
11 | #import
12 |
13 | @implementation UITableView (HeaderSectionPosition)
14 |
15 | BOOL shouldManuallyLayoutHeaderViews;
16 |
17 | + (void) swizzle
18 | {
19 | NSError *error = nil;
20 | [UITableView jr_swizzleMethod:@selector(layoutSubviews) withMethod:@selector(layoutSubviews_swizzle) error:&error];
21 |
22 | if (error != nil) {
23 | NSLog(@"[ERROR] %@", [error localizedDescription]);
24 | }
25 | }
26 |
27 | #pragma mark -
28 | #pragma mark Self
29 |
30 | - (void) layoutSubviews_swizzle
31 | {
32 | [UITableView jr_swizzleMethod:@selector(layoutSubviews) withMethod:@selector(layoutSubviews_swizzle) error:nil];
33 |
34 | [self layoutSubviews];
35 |
36 | [UITableView jr_swizzleMethod:@selector(layoutSubviews) withMethod:@selector(layoutSubviews_swizzle) error:nil];
37 |
38 | if(shouldManuallyLayoutHeaderViews)
39 | [self layoutHeaderViews];
40 | }
41 |
42 | - (void) setHeaderViewInsets:(UIEdgeInsets )_headerViewInsets
43 | {
44 | NSNumber * topValue = [NSNumber numberWithFloat: _headerViewInsets.top];
45 |
46 | objc_setAssociatedObject(self, @selector(headerViewInsets), topValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
47 |
48 | shouldManuallyLayoutHeaderViews = !UIEdgeInsetsEqualToEdgeInsets(_headerViewInsets, UIEdgeInsetsZero);
49 |
50 | [self setNeedsLayout];
51 | }
52 |
53 | -(UIEdgeInsets ) headerViewInsets
54 | {
55 | NSNumber *topValue = objc_getAssociatedObject(self, @selector(headerViewInsets));
56 | UIEdgeInsets convert = UIEdgeInsetsMake([topValue floatValue], 0, 0, 0);
57 | return convert;
58 | }
59 |
60 | #pragma mark Private
61 |
62 | - (void) layoutHeaderViews
63 | {
64 | const NSUInteger numberOfSections = self.numberOfSections;
65 | const UIEdgeInsets contentInset = self.contentInset;
66 | const CGPoint contentOffset = self.contentOffset;
67 |
68 | const CGFloat sectionViewMinimumOriginY = contentOffset.y + contentInset.top + self.headerViewInsets.top;
69 |
70 | // Layout each header view
71 | for(NSUInteger section = 0; section < numberOfSections; section++)
72 | {
73 |
74 | //headerViewForSection:section won't work due to titanium using plain uiviews
75 |
76 | UIView* sectionHeView = [self viewWithTag:100 + section];
77 |
78 | if(sectionHeView == nil)
79 | continue;
80 |
81 | const CGRect sectionFrame = [self rectForSection:section];
82 |
83 | CGRect sectionHeViewFrame = sectionHeView.frame;
84 |
85 | sectionHeViewFrame.origin.y = ((sectionFrame.origin.y < sectionViewMinimumOriginY) ? sectionViewMinimumOriginY : sectionFrame.origin.y);
86 |
87 | // If it's not last section, manually 'stick' it to the below section if needed
88 | if(section < numberOfSections - 1)
89 | {
90 | const CGRect nextSectionFrame = [self rectForSection:section + 1];
91 |
92 | if(CGRectGetMaxY(sectionHeViewFrame) > CGRectGetMinY(nextSectionFrame))
93 | sectionHeViewFrame.origin.y = nextSectionFrame.origin.y - sectionHeViewFrame.size.height;
94 | }
95 |
96 | [sectionHeView setFrame:sectionHeViewFrame];
97 | }
98 | }
99 | @end
100 |
--------------------------------------------------------------------------------
/ComCitytelecomTiparallaxheader_Prefix.pch:
--------------------------------------------------------------------------------
1 |
2 | #ifdef __OBJC__
3 | #import
4 | #import "TiUIListView+ParallaxHeader.h"
5 | #endif
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | TODO: place your license here and we'll include it in the module distribution
2 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Place your license text here. This file will be incorporated with your app at package time.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Parallax Header for ListView
2 |
3 | ## Description
4 |
5 | The Parallax Header module extends the Appcelerator Titanium ListView
6 | Wrapper module for
7 |
8 | https://github.com/apping/APParallaxHeader
9 |
10 | The module is licensed under the MIT license.
11 |
12 | ### Demo Video
13 |
14 | [](http://youtu.be/H_VSO-k_OLw)
15 |
16 | ## Quick Start
17 |
18 | ### Get it [](http://gitt.io/component/com.citytelecom.tiparallaxheader)
19 | Download the latest distribution ZIP-file and consult the [Titanium Documentation](http://docs.appcelerator.com/titanium/latest/#!/guide/Using_a_Module) on how install it, or simply use the [gitTio CLI](http://gitt.io/cli):
20 |
21 | `$ gittio install com.citytelecom.tiparallaxheader`
22 |
23 | ## Author
24 |
25 | **James Chow**
26 | web: http://updatedisplaylist.com
27 | email: james@jc888.co.uk
28 |
29 | ## Credits
30 | [Mathias Amnell](http://twitter.com/amnell) at [Apping AB](http://apping.se) for APParallaxHeader
31 |
32 | http://b2cloud.com.au/tutorial/uitableview-section-header-positions/
33 |
34 | [Mads Møller](http://www.napp.dk) for showing how to override Titanium components
35 |
36 | ## License
37 |
38 | Copyright (c) 2010-2014 James Chow
39 |
40 | Permission is hereby granted, free of charge, to any person obtaining a copy
41 | of this software and associated documentation files (the "Software"), to deal
42 | in the Software without restriction, including without limitation the rights
43 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44 | copies of the Software, and to permit persons to whom the Software is
45 | furnished to do so, subject to the following conditions:
46 |
47 | The above copyright notice and this permission notice shall be included in
48 | all copies or substantial portions of the Software.
49 |
50 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
56 | THE SOFTWARE.
57 |
--------------------------------------------------------------------------------
/TiParallaxHeader.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 45;
7 | objects = {
8 |
9 | /* Begin PBXAggregateTarget section */
10 | 24416B8111C4CA220047AFDD /* Build & Test */ = {
11 | isa = PBXAggregateTarget;
12 | buildConfigurationList = 24416B8A11C4CA520047AFDD /* Build configuration list for PBXAggregateTarget "Build & Test" */;
13 | buildPhases = (
14 | 24416B8011C4CA220047AFDD /* ShellScript */,
15 | );
16 | dependencies = (
17 | 24416B8511C4CA280047AFDD /* PBXTargetDependency */,
18 | );
19 | name = "Build & Test";
20 | productName = "Build & test";
21 | };
22 | /* End PBXAggregateTarget section */
23 |
24 | /* Begin PBXBuildFile section */
25 | 24DD6CF91134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 24DD6CF71134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.h */; };
26 | 24DD6CFA1134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 24DD6CF81134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.m */; };
27 | 24DE9E1111C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.h in Headers */ = {isa = PBXBuildFile; fileRef = 24DE9E0F11C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.h */; };
28 | 24DE9E1211C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.m in Sources */ = {isa = PBXBuildFile; fileRef = 24DE9E1011C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.m */; };
29 | AA747D9F0F9514B9006C5449 /* ComCitytelecomTiparallaxheader_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* ComCitytelecomTiparallaxheader_Prefix.pch */; };
30 | AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };
31 | B935DD5E19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = B935DD5C19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.h */; };
32 | B935DD5F19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = B935DD5D19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.m */; };
33 | B935DD6219003F420058B357 /* TiUIListView+ParallaxHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = B935DD6019003F420058B357 /* TiUIListView+ParallaxHeader.h */; };
34 | B935DD6319003F420058B357 /* TiUIListView+ParallaxHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = B935DD6119003F420058B357 /* TiUIListView+ParallaxHeader.m */; };
35 | B935DD67190040D10058B357 /* NSObject+JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = B935DD65190040D10058B357 /* NSObject+JRSwizzle.h */; };
36 | B935DD68190040D10058B357 /* NSObject+JRSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = B935DD66190040D10058B357 /* NSObject+JRSwizzle.m */; };
37 | B935DD6B190041390058B357 /* UITableView+HeaderSectionPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = B935DD69190041390058B357 /* UITableView+HeaderSectionPosition.h */; };
38 | B935DD6C190041390058B357 /* UITableView+HeaderSectionPosition.m in Sources */ = {isa = PBXBuildFile; fileRef = B935DD6A190041390058B357 /* UITableView+HeaderSectionPosition.m */; };
39 | B935DD6F190041BB0058B357 /* UIScrollView+APParallaxHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = B935DD6D190041BB0058B357 /* UIScrollView+APParallaxHeader.h */; };
40 | B935DD70190041BB0058B357 /* UIScrollView+APParallaxHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = B935DD6E190041BB0058B357 /* UIScrollView+APParallaxHeader.m */; };
41 | B935DD7B19004D840058B357 /* AsyncImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = B935DD7919004D840058B357 /* AsyncImageView.h */; };
42 | B935DD7C19004D840058B357 /* AsyncImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = B935DD7A19004D840058B357 /* AsyncImageView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
43 | /* End PBXBuildFile section */
44 |
45 | /* Begin PBXContainerItemProxy section */
46 | 24416B8411C4CA280047AFDD /* PBXContainerItemProxy */ = {
47 | isa = PBXContainerItemProxy;
48 | containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
49 | proxyType = 1;
50 | remoteGlobalIDString = D2AAC07D0554694100DB518D;
51 | remoteInfo = TiParallaxHeader;
52 | };
53 | /* End PBXContainerItemProxy section */
54 |
55 | /* Begin PBXFileReference section */
56 | 24DD6CF71134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ComCitytelecomTiparallaxheaderModule.h; path = Classes/ComCitytelecomTiparallaxheaderModule.h; sourceTree = ""; };
57 | 24DD6CF81134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ComCitytelecomTiparallaxheaderModule.m; path = Classes/ComCitytelecomTiparallaxheaderModule.m; sourceTree = ""; };
58 | 24DD6D1B1134B66800162E58 /* titanium.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = titanium.xcconfig; sourceTree = ""; };
59 | 24DE9E0F11C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ComCitytelecomTiparallaxheaderModuleAssets.h; path = Classes/ComCitytelecomTiparallaxheaderModuleAssets.h; sourceTree = ""; };
60 | 24DE9E1011C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ComCitytelecomTiparallaxheaderModuleAssets.m; path = Classes/ComCitytelecomTiparallaxheaderModuleAssets.m; sourceTree = ""; };
61 | AA747D9E0F9514B9006C5449 /* ComCitytelecomTiparallaxheader_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComCitytelecomTiparallaxheader_Prefix.pch; sourceTree = SOURCE_ROOT; };
62 | AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
63 | B935DD5C19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "TiUIListViewProxy+ProxyParallaxHeader.h"; path = "Classes/TiUIListViewProxy+ProxyParallaxHeader.h"; sourceTree = ""; };
64 | B935DD5D19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "TiUIListViewProxy+ProxyParallaxHeader.m"; path = "Classes/TiUIListViewProxy+ProxyParallaxHeader.m"; sourceTree = ""; };
65 | B935DD6019003F420058B357 /* TiUIListView+ParallaxHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "TiUIListView+ParallaxHeader.h"; path = "Classes/TiUIListView+ParallaxHeader.h"; sourceTree = ""; };
66 | B935DD6119003F420058B357 /* TiUIListView+ParallaxHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "TiUIListView+ParallaxHeader.m"; path = "Classes/TiUIListView+ParallaxHeader.m"; sourceTree = ""; };
67 | B935DD65190040D10058B357 /* NSObject+JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSObject+JRSwizzle.h"; path = "Classes/NSObject+JRSwizzle.h"; sourceTree = ""; };
68 | B935DD66190040D10058B357 /* NSObject+JRSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSObject+JRSwizzle.m"; path = "Classes/NSObject+JRSwizzle.m"; sourceTree = ""; };
69 | B935DD69190041390058B357 /* UITableView+HeaderSectionPosition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UITableView+HeaderSectionPosition.h"; path = "Classes/UITableView+HeaderSectionPosition.h"; sourceTree = ""; };
70 | B935DD6A190041390058B357 /* UITableView+HeaderSectionPosition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UITableView+HeaderSectionPosition.m"; path = "Classes/UITableView+HeaderSectionPosition.m"; sourceTree = ""; };
71 | B935DD6D190041BB0058B357 /* UIScrollView+APParallaxHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIScrollView+APParallaxHeader.h"; path = "Classes/UIScrollView+APParallaxHeader.h"; sourceTree = ""; };
72 | B935DD6E190041BB0058B357 /* UIScrollView+APParallaxHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIScrollView+APParallaxHeader.m"; path = "Classes/UIScrollView+APParallaxHeader.m"; sourceTree = ""; };
73 | B935DD7919004D840058B357 /* AsyncImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AsyncImageView.h; path = Classes/AsyncImageView.h; sourceTree = ""; };
74 | B935DD7A19004D840058B357 /* AsyncImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AsyncImageView.m; path = Classes/AsyncImageView.m; sourceTree = ""; };
75 | D2AAC07E0554694100DB518D /* libComCitytelecomTiparallaxheader.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libComCitytelecomTiparallaxheader.a; sourceTree = BUILT_PRODUCTS_DIR; };
76 | /* End PBXFileReference section */
77 |
78 | /* Begin PBXFrameworksBuildPhase section */
79 | D2AAC07C0554694100DB518D /* Frameworks */ = {
80 | isa = PBXFrameworksBuildPhase;
81 | buildActionMask = 2147483647;
82 | files = (
83 | AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */,
84 | );
85 | runOnlyForDeploymentPostprocessing = 0;
86 | };
87 | /* End PBXFrameworksBuildPhase section */
88 |
89 | /* Begin PBXGroup section */
90 | 034768DFFF38A50411DB9C8B /* Products */ = {
91 | isa = PBXGroup;
92 | children = (
93 | D2AAC07E0554694100DB518D /* libComCitytelecomTiparallaxheader.a */,
94 | );
95 | name = Products;
96 | sourceTree = "";
97 | };
98 | 0867D691FE84028FC02AAC07 /* TiParallaxHeader */ = {
99 | isa = PBXGroup;
100 | children = (
101 | 08FB77AEFE84172EC02AAC07 /* Classes */,
102 | 32C88DFF0371C24200C91783 /* Other Sources */,
103 | 0867D69AFE84028FC02AAC07 /* Frameworks */,
104 | 034768DFFF38A50411DB9C8B /* Products */,
105 | );
106 | name = TiParallaxHeader;
107 | sourceTree = "";
108 | };
109 | 0867D69AFE84028FC02AAC07 /* Frameworks */ = {
110 | isa = PBXGroup;
111 | children = (
112 | AACBBE490F95108600F1A2B1 /* Foundation.framework */,
113 | );
114 | name = Frameworks;
115 | sourceTree = "";
116 | };
117 | 08FB77AEFE84172EC02AAC07 /* Classes */ = {
118 | isa = PBXGroup;
119 | children = (
120 | B935DD7919004D840058B357 /* AsyncImageView.h */,
121 | B935DD7A19004D840058B357 /* AsyncImageView.m */,
122 | 24DE9E0F11C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.h */,
123 | 24DE9E1011C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.m */,
124 | 24DD6CF71134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.h */,
125 | 24DD6CF81134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.m */,
126 | B935DD5C19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.h */,
127 | B935DD5D19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.m */,
128 | B935DD6019003F420058B357 /* TiUIListView+ParallaxHeader.h */,
129 | B935DD6119003F420058B357 /* TiUIListView+ParallaxHeader.m */,
130 | B935DD65190040D10058B357 /* NSObject+JRSwizzle.h */,
131 | B935DD66190040D10058B357 /* NSObject+JRSwizzle.m */,
132 | B935DD69190041390058B357 /* UITableView+HeaderSectionPosition.h */,
133 | B935DD6A190041390058B357 /* UITableView+HeaderSectionPosition.m */,
134 | B935DD6D190041BB0058B357 /* UIScrollView+APParallaxHeader.h */,
135 | B935DD6E190041BB0058B357 /* UIScrollView+APParallaxHeader.m */,
136 | );
137 | name = Classes;
138 | sourceTree = "";
139 | };
140 | 32C88DFF0371C24200C91783 /* Other Sources */ = {
141 | isa = PBXGroup;
142 | children = (
143 | AA747D9E0F9514B9006C5449 /* ComCitytelecomTiparallaxheader_Prefix.pch */,
144 | 24DD6D1B1134B66800162E58 /* titanium.xcconfig */,
145 | );
146 | name = "Other Sources";
147 | sourceTree = "";
148 | };
149 | /* End PBXGroup section */
150 |
151 | /* Begin PBXHeadersBuildPhase section */
152 | D2AAC07A0554694100DB518D /* Headers */ = {
153 | isa = PBXHeadersBuildPhase;
154 | buildActionMask = 2147483647;
155 | files = (
156 | B935DD6B190041390058B357 /* UITableView+HeaderSectionPosition.h in Headers */,
157 | B935DD5E19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.h in Headers */,
158 | B935DD67190040D10058B357 /* NSObject+JRSwizzle.h in Headers */,
159 | AA747D9F0F9514B9006C5449 /* ComCitytelecomTiparallaxheader_Prefix.pch in Headers */,
160 | 24DD6CF91134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.h in Headers */,
161 | B935DD6219003F420058B357 /* TiUIListView+ParallaxHeader.h in Headers */,
162 | B935DD7B19004D840058B357 /* AsyncImageView.h in Headers */,
163 | 24DE9E1111C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.h in Headers */,
164 | B935DD6F190041BB0058B357 /* UIScrollView+APParallaxHeader.h in Headers */,
165 | );
166 | runOnlyForDeploymentPostprocessing = 0;
167 | };
168 | /* End PBXHeadersBuildPhase section */
169 |
170 | /* Begin PBXNativeTarget section */
171 | D2AAC07D0554694100DB518D /* TiParallaxHeader */ = {
172 | isa = PBXNativeTarget;
173 | buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "TiParallaxHeader" */;
174 | buildPhases = (
175 | D2AAC07A0554694100DB518D /* Headers */,
176 | D2AAC07B0554694100DB518D /* Sources */,
177 | D2AAC07C0554694100DB518D /* Frameworks */,
178 | );
179 | buildRules = (
180 | );
181 | dependencies = (
182 | );
183 | name = TiParallaxHeader;
184 | productName = TiParallaxHeader;
185 | productReference = D2AAC07E0554694100DB518D /* libComCitytelecomTiparallaxheader.a */;
186 | productType = "com.apple.product-type.library.static";
187 | };
188 | /* End PBXNativeTarget section */
189 |
190 | /* Begin PBXProject section */
191 | 0867D690FE84028FC02AAC07 /* Project object */ = {
192 | isa = PBXProject;
193 | attributes = {
194 | };
195 | buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "TiParallaxHeader" */;
196 | compatibilityVersion = "Xcode 3.1";
197 | developmentRegion = English;
198 | hasScannedForEncodings = 1;
199 | knownRegions = (
200 | English,
201 | Japanese,
202 | French,
203 | German,
204 | );
205 | mainGroup = 0867D691FE84028FC02AAC07 /* TiParallaxHeader */;
206 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
207 | projectDirPath = "";
208 | projectRoot = "";
209 | targets = (
210 | D2AAC07D0554694100DB518D /* TiParallaxHeader */,
211 | 24416B8111C4CA220047AFDD /* Build & Test */,
212 | );
213 | };
214 | /* End PBXProject section */
215 |
216 | /* Begin PBXShellScriptBuildPhase section */
217 | 24416B8011C4CA220047AFDD /* ShellScript */ = {
218 | isa = PBXShellScriptBuildPhase;
219 | buildActionMask = 2147483647;
220 | files = (
221 | );
222 | inputPaths = (
223 | );
224 | outputPaths = (
225 | );
226 | runOnlyForDeploymentPostprocessing = 0;
227 | shellPath = /bin/sh;
228 | shellScript = "# shell script goes here\n\npython \"${TITANIUM_SDK}/titanium.py\" run --dir=\"${PROJECT_DIR}\"\nexit $?\n";
229 | };
230 | /* End PBXShellScriptBuildPhase section */
231 |
232 | /* Begin PBXSourcesBuildPhase section */
233 | D2AAC07B0554694100DB518D /* Sources */ = {
234 | isa = PBXSourcesBuildPhase;
235 | buildActionMask = 2147483647;
236 | files = (
237 | 24DD6CFA1134B3F500162E58 /* ComCitytelecomTiparallaxheaderModule.m in Sources */,
238 | B935DD6C190041390058B357 /* UITableView+HeaderSectionPosition.m in Sources */,
239 | B935DD68190040D10058B357 /* NSObject+JRSwizzle.m in Sources */,
240 | 24DE9E1211C5FE74003F90F6 /* ComCitytelecomTiparallaxheaderModuleAssets.m in Sources */,
241 | B935DD70190041BB0058B357 /* UIScrollView+APParallaxHeader.m in Sources */,
242 | B935DD5F19003DEC0058B357 /* TiUIListViewProxy+ProxyParallaxHeader.m in Sources */,
243 | B935DD6319003F420058B357 /* TiUIListView+ParallaxHeader.m in Sources */,
244 | B935DD7C19004D840058B357 /* AsyncImageView.m in Sources */,
245 | );
246 | runOnlyForDeploymentPostprocessing = 0;
247 | };
248 | /* End PBXSourcesBuildPhase section */
249 |
250 | /* Begin PBXTargetDependency section */
251 | 24416B8511C4CA280047AFDD /* PBXTargetDependency */ = {
252 | isa = PBXTargetDependency;
253 | target = D2AAC07D0554694100DB518D /* TiParallaxHeader */;
254 | targetProxy = 24416B8411C4CA280047AFDD /* PBXContainerItemProxy */;
255 | };
256 | /* End PBXTargetDependency section */
257 |
258 | /* Begin XCBuildConfiguration section */
259 | 1DEB921F08733DC00010E9CD /* Debug */ = {
260 | isa = XCBuildConfiguration;
261 | baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
262 | buildSettings = {
263 | CODE_SIGN_IDENTITY = "iPhone Developer";
264 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
265 | DSTROOT = /tmp/ComCitytelecomTiparallaxheader.dst;
266 | GCC_C_LANGUAGE_STANDARD = c99;
267 | GCC_OPTIMIZATION_LEVEL = 0;
268 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
269 | GCC_PREFIX_HEADER = ComCitytelecomTiparallaxheader_Prefix.pch;
270 | GCC_PREPROCESSOR_DEFINITIONS = "TI_VERSION=$(TI_VERSION)";
271 | GCC_TREAT_WARNINGS_AS_ERRORS = NO;
272 | GCC_VERSION = "";
273 | GCC_WARN_ABOUT_RETURN_TYPE = NO;
274 | GCC_WARN_MISSING_PARENTHESES = NO;
275 | GCC_WARN_SHADOW = NO;
276 | GCC_WARN_STRICT_SELECTOR_MATCH = NO;
277 | GCC_WARN_UNUSED_FUNCTION = YES;
278 | GCC_WARN_UNUSED_PARAMETER = NO;
279 | GCC_WARN_UNUSED_VALUE = NO;
280 | GCC_WARN_UNUSED_VARIABLE = NO;
281 | INSTALL_PATH = /usr/local/lib;
282 | LIBRARY_SEARCH_PATHS = "";
283 | OTHER_CFLAGS = (
284 | "-DDEBUG",
285 | "-DTI_POST_1_2",
286 | );
287 | OTHER_LDFLAGS = "-ObjC";
288 | PRODUCT_NAME = ComCitytelecomTiparallaxheader;
289 | PROVISIONING_PROFILE = "";
290 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
291 | RUN_CLANG_STATIC_ANALYZER = NO;
292 | SDKROOT = iphoneos;
293 | USER_HEADER_SEARCH_PATHS = "";
294 | };
295 | name = Debug;
296 | };
297 | 1DEB922008733DC00010E9CD /* Release */ = {
298 | isa = XCBuildConfiguration;
299 | baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
300 | buildSettings = {
301 | ALWAYS_SEARCH_USER_PATHS = NO;
302 | DSTROOT = /tmp/ComCitytelecomTiparallaxheader.dst;
303 | GCC_C_LANGUAGE_STANDARD = c99;
304 | GCC_MODEL_TUNING = G5;
305 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
306 | GCC_PREFIX_HEADER = ComCitytelecomTiparallaxheader_Prefix.pch;
307 | GCC_PREPROCESSOR_DEFINITIONS = "TI_VERSION=$(TI_VERSION)";
308 | GCC_TREAT_WARNINGS_AS_ERRORS = NO;
309 | GCC_VERSION = "";
310 | GCC_WARN_ABOUT_RETURN_TYPE = NO;
311 | GCC_WARN_MISSING_PARENTHESES = NO;
312 | GCC_WARN_SHADOW = NO;
313 | GCC_WARN_STRICT_SELECTOR_MATCH = NO;
314 | GCC_WARN_UNUSED_FUNCTION = YES;
315 | GCC_WARN_UNUSED_PARAMETER = NO;
316 | GCC_WARN_UNUSED_VALUE = NO;
317 | GCC_WARN_UNUSED_VARIABLE = NO;
318 | INSTALL_PATH = /usr/local/lib;
319 | IPHONEOS_DEPLOYMENT_TARGET = 4.0;
320 | LIBRARY_SEARCH_PATHS = "";
321 | OTHER_CFLAGS = "-DTI_POST_1_2";
322 | OTHER_LDFLAGS = "-ObjC";
323 | PRODUCT_NAME = ComCitytelecomTiparallaxheader;
324 | RUN_CLANG_STATIC_ANALYZER = NO;
325 | SDKROOT = iphoneos;
326 | USER_HEADER_SEARCH_PATHS = "";
327 | };
328 | name = Release;
329 | };
330 | 1DEB922308733DC00010E9CD /* Debug */ = {
331 | isa = XCBuildConfiguration;
332 | baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
333 | buildSettings = {
334 | CODE_SIGN_IDENTITY = "iPhone Developer";
335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
336 | DSTROOT = /tmp/ComCitytelecomTiparallaxheader.dst;
337 | GCC_C_LANGUAGE_STANDARD = c99;
338 | GCC_OPTIMIZATION_LEVEL = 0;
339 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
340 | GCC_PREFIX_HEADER = ComCitytelecomTiparallaxheader_Prefix.pch;
341 | GCC_PREPROCESSOR_DEFINITIONS = "TI_VERSION=$(TI_VERSION)";
342 | GCC_TREAT_WARNINGS_AS_ERRORS = NO;
343 | GCC_VERSION = "";
344 | GCC_WARN_ABOUT_RETURN_TYPE = NO;
345 | GCC_WARN_MISSING_PARENTHESES = NO;
346 | GCC_WARN_SHADOW = NO;
347 | GCC_WARN_STRICT_SELECTOR_MATCH = NO;
348 | GCC_WARN_UNUSED_FUNCTION = YES;
349 | GCC_WARN_UNUSED_PARAMETER = NO;
350 | GCC_WARN_UNUSED_VALUE = NO;
351 | GCC_WARN_UNUSED_VARIABLE = NO;
352 | INSTALL_PATH = /usr/local/lib;
353 | OTHER_CFLAGS = (
354 | "-DDEBUG",
355 | "-DTI_POST_1_2",
356 | );
357 | OTHER_LDFLAGS = "-ObjC";
358 | PRODUCT_NAME = ComCitytelecomTiparallaxheader;
359 | PROVISIONING_PROFILE = "";
360 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
361 | RUN_CLANG_STATIC_ANALYZER = NO;
362 | SDKROOT = iphoneos;
363 | USER_HEADER_SEARCH_PATHS = "";
364 | };
365 | name = Debug;
366 | };
367 | 1DEB922408733DC00010E9CD /* Release */ = {
368 | isa = XCBuildConfiguration;
369 | baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
370 | buildSettings = {
371 | ALWAYS_SEARCH_USER_PATHS = NO;
372 | DSTROOT = /tmp/ComCitytelecomTiparallaxheader.dst;
373 | GCC_C_LANGUAGE_STANDARD = c99;
374 | GCC_MODEL_TUNING = G5;
375 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
376 | GCC_PREFIX_HEADER = ComCitytelecomTiparallaxheader_Prefix.pch;
377 | GCC_PREPROCESSOR_DEFINITIONS = "TI_VERSION=$(TI_VERSION)";
378 | GCC_TREAT_WARNINGS_AS_ERRORS = NO;
379 | GCC_VERSION = "";
380 | GCC_WARN_ABOUT_RETURN_TYPE = NO;
381 | GCC_WARN_MISSING_PARENTHESES = NO;
382 | GCC_WARN_SHADOW = NO;
383 | GCC_WARN_STRICT_SELECTOR_MATCH = NO;
384 | GCC_WARN_UNUSED_FUNCTION = YES;
385 | GCC_WARN_UNUSED_PARAMETER = NO;
386 | GCC_WARN_UNUSED_VALUE = NO;
387 | GCC_WARN_UNUSED_VARIABLE = NO;
388 | INSTALL_PATH = /usr/local/lib;
389 | IPHONEOS_DEPLOYMENT_TARGET = 4.0;
390 | OTHER_CFLAGS = "-DTI_POST_1_2";
391 | OTHER_LDFLAGS = "-ObjC";
392 | PRODUCT_NAME = ComCitytelecomTiparallaxheader;
393 | RUN_CLANG_STATIC_ANALYZER = NO;
394 | SDKROOT = iphoneos;
395 | USER_HEADER_SEARCH_PATHS = "";
396 | };
397 | name = Release;
398 | };
399 | 24416B8211C4CA220047AFDD /* Debug */ = {
400 | isa = XCBuildConfiguration;
401 | baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
402 | buildSettings = {
403 | COPY_PHASE_STRIP = NO;
404 | GCC_DYNAMIC_NO_PIC = NO;
405 | GCC_OPTIMIZATION_LEVEL = 0;
406 | PRODUCT_NAME = "Build & test";
407 | };
408 | name = Debug;
409 | };
410 | 24416B8311C4CA220047AFDD /* Release */ = {
411 | isa = XCBuildConfiguration;
412 | baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
413 | buildSettings = {
414 | COPY_PHASE_STRIP = YES;
415 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
416 | GCC_ENABLE_FIX_AND_CONTINUE = NO;
417 | PRODUCT_NAME = "Build & test";
418 | ZERO_LINK = NO;
419 | };
420 | name = Release;
421 | };
422 | /* End XCBuildConfiguration section */
423 |
424 | /* Begin XCConfigurationList section */
425 | 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "TiParallaxHeader" */ = {
426 | isa = XCConfigurationList;
427 | buildConfigurations = (
428 | 1DEB921F08733DC00010E9CD /* Debug */,
429 | 1DEB922008733DC00010E9CD /* Release */,
430 | );
431 | defaultConfigurationIsVisible = 0;
432 | defaultConfigurationName = Release;
433 | };
434 | 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "TiParallaxHeader" */ = {
435 | isa = XCConfigurationList;
436 | buildConfigurations = (
437 | 1DEB922308733DC00010E9CD /* Debug */,
438 | 1DEB922408733DC00010E9CD /* Release */,
439 | );
440 | defaultConfigurationIsVisible = 0;
441 | defaultConfigurationName = Release;
442 | };
443 | 24416B8A11C4CA520047AFDD /* Build configuration list for PBXAggregateTarget "Build & Test" */ = {
444 | isa = XCConfigurationList;
445 | buildConfigurations = (
446 | 24416B8211C4CA220047AFDD /* Debug */,
447 | 24416B8311C4CA220047AFDD /* Release */,
448 | );
449 | defaultConfigurationIsVisible = 0;
450 | defaultConfigurationName = Release;
451 | };
452 | /* End XCConfigurationList section */
453 | };
454 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
455 | }
456 |
--------------------------------------------------------------------------------
/TiParallaxHeader.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TiParallaxHeader.xcodeproj/project.xcworkspace/xcuserdata/jameschow.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jc888/TiParallaxHeader/ec3491422b49e384bd83d13e4cdf0aceb1fb1b7d/TiParallaxHeader.xcodeproj/project.xcworkspace/xcuserdata/jameschow.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/TiParallaxHeader.xcodeproj/xcuserdata/jameschow.xcuserdatad/xcschemes/Build & Test.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
42 |
43 |
44 |
45 |
51 |
52 |
54 |
55 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/TiParallaxHeader.xcodeproj/xcuserdata/jameschow.xcuserdatad/xcschemes/TiParallaxHeader.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
42 |
43 |
44 |
45 |
51 |
52 |
54 |
55 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/TiParallaxHeader.xcodeproj/xcuserdata/jameschow.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Build & Test.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | TiParallaxHeader.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 24416B8111C4CA220047AFDD
21 |
22 | primary
23 |
24 |
25 | D2AAC07D0554694100DB518D
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/assets/README:
--------------------------------------------------------------------------------
1 | Place your assets like PNG files in this directory and they will be packaged with your module.
2 |
3 | If you create a file named com.citytelecom.tiparallaxheader.js in this directory, it will be
4 | compiled and used as your module. This allows you to run pure Javascript
5 | modules that are pre-compiled.
6 |
7 |
--------------------------------------------------------------------------------
/assets/com.citytelecom.tiparallaxheader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author James Chow
3 | */
4 | Ti.UI.createListView();
--------------------------------------------------------------------------------
/build.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Appcelerator Titanium Module Packager
4 | #
5 | #
6 | import os, subprocess, sys, glob, string, optparse, subprocess
7 | import zipfile
8 | from datetime import date
9 |
10 | cwd = os.path.abspath(os.path.dirname(sys._getframe(0).f_code.co_filename))
11 | os.chdir(cwd)
12 | required_module_keys = ['name','version','moduleid','description','copyright','license','copyright','platform','minsdk']
13 | module_defaults = {
14 | 'description':'My module',
15 | 'author': 'Your Name',
16 | 'license' : 'Specify your license',
17 | 'copyright' : 'Copyright (c) %s by Your Company' % str(date.today().year),
18 | }
19 | module_license_default = "TODO: place your license here and we'll include it in the module distribution"
20 |
21 | def find_sdk(config):
22 | sdk = config['TITANIUM_SDK']
23 | return os.path.expandvars(os.path.expanduser(sdk))
24 |
25 | def replace_vars(config,token):
26 | idx = token.find('$(')
27 | while idx != -1:
28 | idx2 = token.find(')',idx+2)
29 | if idx2 == -1: break
30 | key = token[idx+2:idx2]
31 | if not config.has_key(key): break
32 | token = token.replace('$(%s)' % key, config[key])
33 | idx = token.find('$(')
34 | return token
35 |
36 |
37 | def read_ti_xcconfig():
38 | contents = open(os.path.join(cwd,'titanium.xcconfig')).read()
39 | config = {}
40 | for line in contents.splitlines(False):
41 | line = line.strip()
42 | if line[0:2]=='//': continue
43 | idx = line.find('=')
44 | if idx > 0:
45 | key = line[0:idx].strip()
46 | value = line[idx+1:].strip()
47 | config[key] = replace_vars(config,value)
48 | return config
49 |
50 | def generate_doc(config):
51 | docdir = os.path.join(cwd,'documentation')
52 | if not os.path.exists(docdir):
53 | warn("Couldn't find documentation file at: %s" % docdir)
54 | return None
55 |
56 | try:
57 | import markdown2 as markdown
58 | except ImportError:
59 | import markdown
60 | documentation = []
61 | for file in os.listdir(docdir):
62 | if file in ignoreFiles or os.path.isdir(os.path.join(docdir, file)):
63 | continue
64 | md = open(os.path.join(docdir,file)).read()
65 | html = markdown.markdown(md)
66 | documentation.append({file:html});
67 | return documentation
68 |
69 | def compile_js(manifest,config):
70 | js_file = os.path.join(cwd,'assets','com.citytelecom.tiparallaxheader.js')
71 | if not os.path.exists(js_file): return
72 |
73 | from compiler import Compiler
74 | try:
75 | import json
76 | except:
77 | import simplejson as json
78 |
79 | compiler = Compiler(cwd, manifest['moduleid'], manifest['name'], 'commonjs')
80 | root_asset, module_assets = compiler.compile_module()
81 |
82 | root_asset_content = """
83 | %s
84 |
85 | return filterDataInRange([NSData dataWithBytesNoCopy:data length:sizeof(data) freeWhenDone:NO], ranges[0]);
86 | """ % root_asset
87 |
88 | module_asset_content = """
89 | %s
90 |
91 | NSNumber *index = [map objectForKey:path];
92 | if (index == nil) {
93 | return nil;
94 | }
95 | return filterDataInRange([NSData dataWithBytesNoCopy:data length:sizeof(data) freeWhenDone:NO], ranges[index.integerValue]);
96 | """ % module_assets
97 |
98 | from tools import splice_code
99 |
100 | assets_router = os.path.join(cwd,'Classes','ComCitytelecomTiparallaxheaderModuleAssets.m')
101 | splice_code(assets_router, 'asset', root_asset_content)
102 | splice_code(assets_router, 'resolve_asset', module_asset_content)
103 |
104 | # Generate the exports after crawling all of the available JS source
105 | exports = open('metadata.json','w')
106 | json.dump({'exports':compiler.exports }, exports)
107 | exports.close()
108 |
109 | def die(msg):
110 | print msg
111 | sys.exit(1)
112 |
113 | def info(msg):
114 | print "[INFO] %s" % msg
115 |
116 | def warn(msg):
117 | print "[WARN] %s" % msg
118 |
119 | def validate_license():
120 | c = open(os.path.join(cwd,'LICENSE')).read()
121 | if c.find(module_license_default)!=-1:
122 | warn('please update the LICENSE file with your license text before distributing')
123 |
124 | def validate_manifest():
125 | path = os.path.join(cwd,'manifest')
126 | f = open(path)
127 | if not os.path.exists(path): die("missing %s" % path)
128 | manifest = {}
129 | for line in f.readlines():
130 | line = line.strip()
131 | if line[0:1]=='#': continue
132 | if line.find(':') < 0: continue
133 | key,value = line.split(':')
134 | manifest[key.strip()]=value.strip()
135 | for key in required_module_keys:
136 | if not manifest.has_key(key): die("missing required manifest key '%s'" % key)
137 | if module_defaults.has_key(key):
138 | defvalue = module_defaults[key]
139 | curvalue = manifest[key]
140 | if curvalue==defvalue: warn("please update the manifest key: '%s' to a non-default value" % key)
141 | return manifest,path
142 |
143 | ignoreFiles = ['.DS_Store','.gitignore','libTitanium.a','titanium.jar','README']
144 | ignoreDirs = ['.DS_Store','.svn','.git','CVSROOT']
145 |
146 | def zip_dir(zf,dir,basepath,ignoreExt=[]):
147 | if not os.path.exists(dir): return
148 | for root, dirs, files in os.walk(dir):
149 | for name in ignoreDirs:
150 | if name in dirs:
151 | dirs.remove(name) # don't visit ignored directories
152 | for file in files:
153 | if file in ignoreFiles: continue
154 | e = os.path.splitext(file)
155 | if len(e) == 2 and e[1] in ignoreExt: continue
156 | from_ = os.path.join(root, file)
157 | to_ = from_.replace(dir, '%s/%s'%(basepath,dir), 1)
158 | zf.write(from_, to_)
159 |
160 | def glob_libfiles():
161 | files = []
162 | for libfile in glob.glob('build/**/*.a'):
163 | if libfile.find('Release-')!=-1:
164 | files.append(libfile)
165 | return files
166 |
167 | def build_module(manifest,config):
168 | from tools import ensure_dev_path
169 | ensure_dev_path()
170 |
171 | rc = os.system("xcodebuild -sdk iphoneos -configuration Release")
172 | if rc != 0:
173 | die("xcodebuild failed")
174 | rc = os.system("xcodebuild -sdk iphonesimulator -configuration Release")
175 | if rc != 0:
176 | die("xcodebuild failed")
177 | # build the merged library using lipo
178 | moduleid = manifest['moduleid']
179 | libpaths = ''
180 | for libfile in glob_libfiles():
181 | libpaths+='%s ' % libfile
182 |
183 | os.system("lipo %s -create -output build/lib%s.a" %(libpaths,moduleid))
184 |
185 | def generate_apidoc(apidoc_build_path):
186 | global options
187 |
188 | if options.skip_docs:
189 | info("Skipping documentation generation.")
190 | return False
191 | else:
192 | info("Module apidoc generation can be skipped using --skip-docs")
193 | apidoc_path = os.path.join(cwd, "apidoc")
194 | if not os.path.exists(apidoc_path):
195 | warn("Skipping apidoc generation. No apidoc folder found at: %s" % apidoc_path)
196 | return False
197 |
198 | if not os.path.exists(apidoc_build_path):
199 | os.makedirs(apidoc_build_path)
200 | ti_root = string.strip(subprocess.check_output(["echo $TI_ROOT"], shell=True))
201 | if not len(ti_root) > 0:
202 | warn("Not generating documentation from the apidoc folder. The titanium_mobile repo could not be found.")
203 | warn("Set the TI_ROOT environment variable to the parent folder where the titanium_mobile repo resides (eg.'export TI_ROOT=/Path').")
204 | return False
205 | docgen = os.path.join(ti_root, "titanium_mobile", "apidoc", "docgen.py")
206 | if not os.path.exists(docgen):
207 | warn("Not generating documentation from the apidoc folder. Couldn't find docgen.py at: %s" % docgen)
208 | return False
209 |
210 | info("Generating documentation from the apidoc folder.")
211 | rc = os.system("\"%s\" --format=jsca,modulehtml --css=styles.css -o \"%s\" -e \"%s\"" % (docgen, apidoc_build_path, apidoc_path))
212 | if rc != 0:
213 | die("docgen failed")
214 | return True
215 |
216 | def package_module(manifest,mf,config):
217 | name = manifest['name'].lower()
218 | moduleid = manifest['moduleid'].lower()
219 | version = manifest['version']
220 | modulezip = '%s-iphone-%s.zip' % (moduleid,version)
221 | if os.path.exists(modulezip): os.remove(modulezip)
222 | zf = zipfile.ZipFile(modulezip, 'w', zipfile.ZIP_DEFLATED)
223 | modulepath = 'modules/iphone/%s/%s' % (moduleid,version)
224 | zf.write(mf,'%s/manifest' % modulepath)
225 | libname = 'lib%s.a' % moduleid
226 | zf.write('build/%s' % libname, '%s/%s' % (modulepath,libname))
227 | docs = generate_doc(config)
228 | if docs!=None:
229 | for doc in docs:
230 | for file, html in doc.iteritems():
231 | filename = string.replace(file,'.md','.html')
232 | zf.writestr('%s/documentation/%s'%(modulepath,filename),html)
233 |
234 | apidoc_build_path = os.path.join(cwd, "build", "apidoc")
235 | if generate_apidoc(apidoc_build_path):
236 | for file in os.listdir(apidoc_build_path):
237 | if file in ignoreFiles or os.path.isdir(os.path.join(apidoc_build_path, file)):
238 | continue
239 | zf.write(os.path.join(apidoc_build_path, file), '%s/documentation/apidoc/%s' % (modulepath, file))
240 |
241 | zip_dir(zf,'assets',modulepath,['.pyc','.js'])
242 | zip_dir(zf,'example',modulepath,['.pyc'])
243 | zip_dir(zf,'platform',modulepath,['.pyc','.js'])
244 | zf.write('LICENSE','%s/LICENSE' % modulepath)
245 | zf.write('module.xcconfig','%s/module.xcconfig' % modulepath)
246 | exports_file = 'metadata.json'
247 | if os.path.exists(exports_file):
248 | zf.write(exports_file, '%s/%s' % (modulepath, exports_file))
249 | zf.close()
250 |
251 |
252 | if __name__ == '__main__':
253 | global options
254 |
255 | parser = optparse.OptionParser()
256 | parser.add_option("-s", "--skip-docs",
257 | dest="skip_docs",
258 | action="store_true",
259 | help="Will skip building documentation in apidoc folder",
260 | default=False)
261 | (options, args) = parser.parse_args()
262 |
263 | manifest,mf = validate_manifest()
264 | validate_license()
265 | config = read_ti_xcconfig()
266 |
267 | sdk = find_sdk(config)
268 | sys.path.insert(0,os.path.join(sdk,'iphone'))
269 | sys.path.append(os.path.join(sdk, "common"))
270 |
271 | compile_js(manifest,config)
272 | build_module(manifest,config)
273 | package_module(manifest,mf,config)
274 | sys.exit(0)
275 |
276 |
--------------------------------------------------------------------------------
/com.citytelecom.tiparallaxheader-iphone-0.1.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jc888/TiParallaxHeader/ec3491422b49e384bd83d13e4cdf0aceb1fb1b7d/com.citytelecom.tiparallaxheader-iphone-0.1.zip
--------------------------------------------------------------------------------
/dist/com.citytelecom.tiparallaxheader-iphone-0.1.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jc888/TiParallaxHeader/ec3491422b49e384bd83d13e4cdf0aceb1fb1b7d/dist/com.citytelecom.tiparallaxheader-iphone-0.1.zip
--------------------------------------------------------------------------------
/dist/com.citytelecom.tiparallaxheader-iphone-0.2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jc888/TiParallaxHeader/ec3491422b49e384bd83d13e4cdf0aceb1fb1b7d/dist/com.citytelecom.tiparallaxheader-iphone-0.2.zip
--------------------------------------------------------------------------------
/documentation/index.md:
--------------------------------------------------------------------------------
1 | # TiParallaxHeader Module
2 |
3 | ### Demo Video
4 |
5 | [](http://youtu.be/H_VSO-k_OLw)
6 |
7 | ## Description
8 |
9 | Insert a slightly bouncy parallax scrolling header for a Titanium ListView.
10 | Similar effect to Spotify/Path apps.
11 |
12 | ## Referencing the module in your Ti mobile application
13 |
14 | Simply add the following lines to your `tiapp.xml` file:
15 |
16 |
17 | com.citytelecom.tiparallaxheader
18 |
19 |
20 | ## Accessing the TiParallaxHeader Module
21 |
22 | To access this module from JavaScript, you would do the following:
23 |
24 | ```javascript
25 | var TiParallaxHeader = require("com.citytelecom.tiparallaxheader");
26 | ```
27 |
28 | Do this only once for your app, preferably in your app.js / alloy.js file.
29 | This will extend ListView with additional methods
30 |
31 |
32 | ## Usage
33 |
34 | ListView will be extended with the following methods. Only call them after the ListView has finished renderering, by listening to the 'postlayout' event
35 |
36 | ```javascript
37 | function onListViewPostlayout(e) {
38 | // attach the parallax header
39 | listView.addParallaxWithImage('http://example.com/image.png', 350);
40 | }
41 | //must wait till ListView has sized itself
42 | listView.addEventListener('postlayout',onListViewPostlayout);
43 | ```
44 | ## ListView functions
45 |
46 | ### addParallaxWithImage
47 |
48 | Add an expanding parallax image for the background of the header
49 |
50 | local file
51 | ```javascript
52 | var url = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, 'ParallaxImage.jpg').nativePath;
53 | var headerHeight = 350;
54 | listView.addParallaxWithImage(url, headerHeight);
55 | ```
56 |
57 | Remote file
58 | ```javascript
59 | listView.addParallaxWithImage('http://example.com/image.png', 350);
60 | ```
61 |
62 | ### addParallaxWithView
63 | Add a titanium View to the header, automatically set to resize within header area
64 |
65 | ```javascript
66 | var headerView = Ti.UI.createView({
67 | backgroundColor:'red'
68 | });
69 |
70 | //this will reparent the headerView
71 | listView.addParallaxWithView(headerView, 350);
72 | ```
73 |
74 | ### setSectionHeaderInset
75 | Insetting the header into the listview, causes all sticky ListView section headers to stick below the header height.
76 | This method allows giving an offset to the Y position of the headers.
77 |
78 | ```javascript
79 | listView.setSectionHeaderInset(-350);
80 | ```
81 |
82 | ### setFadeoutOverHeight
83 | Calling this method will create a fade out effect of the HeaderView, when scrolling greater then the header height.
84 | Accepts a single parameter, of a height in pixels.
85 |
86 | ```javascript
87 | //pulling the scroll so that the header expands beyond the height (>350) within 50 pixels the view will gradually fade
88 | listView.setFadeoutOverHeight(50)
89 | ```
90 |
91 | ## Author
92 |
93 | **James Chow**
94 | web: http://updatedisplaylist.com
95 | email: james@jc888.co.uk
96 |
97 | ## License
98 |
99 | Copyright (c) 2010-2014 James Chow
100 |
101 | Permission is hereby granted, free of charge, to any person obtaining a copy
102 | of this software and associated documentation files (the "Software"), to deal
103 | in the Software without restriction, including without limitation the rights
104 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
105 | copies of the Software, and to permit persons to whom the Software is
106 | furnished to do so, subject to the following conditions:
107 |
108 | The above copyright notice and this permission notice shall be included in
109 | all copies or substantial portions of the Software.
110 |
111 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
112 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
113 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
114 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
115 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
116 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
117 | THE SOFTWARE.
118 |
--------------------------------------------------------------------------------
/example/ParallaxImage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jc888/TiParallaxHeader/ec3491422b49e384bd83d13e4cdf0aceb1fb1b7d/example/ParallaxImage.jpg
--------------------------------------------------------------------------------
/example/app.js:
--------------------------------------------------------------------------------
1 | //import the module
2 | //NOTE : IMPORT ONLY ONCE, for Alloy run in app.js
3 | var TiParallaxHeader = require('com.citytelecom.tiparallaxheader');
4 |
5 | // open a single window
6 | var win = Ti.UI.createWindow({
7 | backgroundColor : 'white'
8 | });
9 |
10 | // ==== NavBar ====
11 | var NAVBAR_HEIGHT = 50;
12 | var navbar = Ti.UI.createLabel({top : 0, width : '100%', height : NAVBAR_HEIGHT, opacity:0.8, backgroundColor : '#0000ff', text:'See through Navbar'});
13 | // ==== NavBar ====
14 |
15 | //height of the Parallax header, does not except DP
16 | var PARALLAX_HEADER_HEIGHT = 350;
17 |
18 | // ==== Parallax Header View ====
19 | var headerView = Ti.UI.createView({
20 | width : Ti.UI.FILL,
21 | height : PARALLAX_HEADER_HEIGHT
22 | });
23 |
24 | var shadowView = Ti.UI.createView({
25 | width : Ti.UI.FILL,
26 | height : Ti.UI.FILL,
27 | backgroundColor:'black',
28 | opacity:'0.5'
29 | });
30 |
31 | var view1 = Ti.UI.createLabel({width : '150dp', height : '150dp', backgroundColor : '#ffdddd', text:'Swipe Me right'});
32 | var view2 = Ti.UI.createLabel({width : '150dp', height : '150dp',backgroundColor : '#ddffdd', text:'Swipe Me left'});
33 |
34 | var scrollableView = Ti.UI.createScrollableView({
35 | width : Ti.UI.FILL,
36 | height : '150dp',
37 | views : [view1, view2]
38 | });
39 |
40 | headerView.add(scrollableView);
41 | headerView.add(shadowView);
42 |
43 | // ==== List View ====
44 | var listView = Ti.UI.createListView({
45 | width : Ti.UI.FILL,
46 | height : Ti.UI.FILL
47 | });
48 |
49 | var section = Ti.UI.createListSection();
50 |
51 | //Floating section header view
52 | var sectionHeaderView = Ti.UI.createLabel({
53 | width : Ti.UI.FILL,
54 | height:'50dp',
55 | backgroundColor:'red',
56 | text:'Section Header'
57 | });
58 | section.setHeaderView(sectionHeaderView);
59 |
60 | //rows
61 | var items = [];
62 | for (var i = 0; i < 20; i++) {
63 | items[i] = {properties : {title : 'Item' + i}};
64 | }
65 | section.setItems(items);
66 | listView.setSections([section]);
67 |
68 | function onListViewPostlayout(e) {
69 |
70 | //Parallax Image Background Image, remote / local urls accepted
71 | var imagePath = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, 'ParallaxImage.jpg').nativePath;
72 | listView.addParallaxWithImage(imagePath, PARALLAX_HEADER_HEIGHT);
73 |
74 | //Parallax HeaderView
75 | listView.addParallaxWithView(headerView, PARALLAX_HEADER_HEIGHT);
76 |
77 | // === Sticky ListView section header ===
78 | // adding a parallax header will cause the sticky section headers in your ListView,
79 | // to stick below the parallax header height, use this method to offset their sticky position.
80 | listView.setSectionHeaderInset(-PARALLAX_HEADER_HEIGHT + NAVBAR_HEIGHT);
81 |
82 | //Fadeout headerview within the space of X pixels above the header height
83 | listView.setFadeoutOverHeight(50);
84 |
85 | //Scroll to first item to force redraw of list
86 | listView.scrollToItem(0, 0);
87 | }
88 |
89 | //must wait till ListView has sized itself
90 | win.addEventListener('open',onListViewPostlayout);
91 |
92 | win.add(listView);
93 | win.add(navbar);
94 | win.open();
95 |
96 |
--------------------------------------------------------------------------------
/hooks/README:
--------------------------------------------------------------------------------
1 | These files are not yet supported as of 1.4.0 but will be in a near future release.
2 |
--------------------------------------------------------------------------------
/hooks/add.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # This is the module project add hook that will be
4 | # called when your module is added to a project
5 | #
6 | import os, sys
7 |
8 | def dequote(s):
9 | if s[0:1] == '"':
10 | return s[1:-1]
11 | return s
12 |
13 | def main(args,argc):
14 | # You will get the following command line arguments
15 | # in the following order:
16 | #
17 | # project_dir = the full path to the project root directory
18 | # project_type = the type of project (desktop, mobile, ipad)
19 | # project_name = the name of the project
20 | #
21 | project_dir = dequote(os.path.expanduser(args[1]))
22 | project_type = dequote(args[2])
23 | project_name = dequote(args[3])
24 |
25 | # TODO: write your add hook here (optional)
26 |
27 |
28 | # exit
29 | sys.exit(0)
30 |
31 |
32 |
33 | if __name__ == '__main__':
34 | main(sys.argv,len(sys.argv))
35 |
36 |
--------------------------------------------------------------------------------
/hooks/install.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # This is the module install hook that will be
4 | # called when your module is first installed
5 | #
6 | import os, sys
7 |
8 | def main(args,argc):
9 |
10 | # TODO: write your install hook here (optional)
11 |
12 | # exit
13 | sys.exit(0)
14 |
15 |
16 |
17 | if __name__ == '__main__':
18 | main(sys.argv,len(sys.argv))
19 |
20 |
--------------------------------------------------------------------------------
/hooks/remove.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # This is the module project remove hook that will be
4 | # called when your module is remove from a project
5 | #
6 | import os, sys
7 |
8 | def dequote(s):
9 | if s[0:1] == '"':
10 | return s[1:-1]
11 | return s
12 |
13 | def main(args,argc):
14 | # You will get the following command line arguments
15 | # in the following order:
16 | #
17 | # project_dir = the full path to the project root directory
18 | # project_type = the type of project (desktop, mobile, ipad)
19 | # project_name = the name of the project
20 | #
21 | project_dir = dequote(os.path.expanduser(args[1]))
22 | project_type = dequote(args[2])
23 | project_name = dequote(args[3])
24 |
25 | # TODO: write your remove hook here (optional)
26 |
27 | # exit
28 | sys.exit(0)
29 |
30 |
31 |
32 | if __name__ == '__main__':
33 | main(sys.argv,len(sys.argv))
34 |
35 |
--------------------------------------------------------------------------------
/hooks/uninstall.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # This is the module uninstall hook that will be
4 | # called when your module is uninstalled
5 | #
6 | import os, sys
7 |
8 | def main(args,argc):
9 |
10 | # TODO: write your uninstall hook here (optional)
11 |
12 | # exit
13 | sys.exit(0)
14 |
15 |
16 | if __name__ == '__main__':
17 | main(sys.argv,len(sys.argv))
18 |
19 |
--------------------------------------------------------------------------------
/manifest:
--------------------------------------------------------------------------------
1 | #
2 | # this is your module manifest and used by Titanium
3 | # during compilation, packaging, distribution, etc.
4 | #
5 | version: 0.2
6 | apiversion: 3
7 | description: Parallax HeaderView for the Titanium ListView
8 | author: James Chow
9 | license: MIT
10 | copyright: City Telecom Services ltd
11 |
12 |
13 | # these should not be edited
14 | name: TiParallaxHeader
15 | moduleid: com.citytelecom.tiparallaxheader
16 | guid: d9d5b1e0-b0fc-4814-bb86-41dc12db6808
17 | platform: iphone
18 | minsdk: 3.2.1.GA
19 |
--------------------------------------------------------------------------------
/metadata.json:
--------------------------------------------------------------------------------
1 | {"exports": ["UI.createListView", "UI.createListView"]}
--------------------------------------------------------------------------------
/module.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | // PLACE ANY BUILD DEFINITIONS IN THIS FILE AND THEY WILL BE
3 | // PICKED UP DURING THE APP BUILD FOR YOUR MODULE
4 | //
5 | // see the following webpage for instructions on the settings
6 | // for this file:
7 | // http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeBuildSystem/400-Build_Configurations/build_configs.html
8 | //
9 |
10 | //
11 | // How to add a Framework (example)
12 | //
13 | // OTHER_LDFLAGS=$(inherited) -framework Foo
14 | //
15 | // Adding a framework for a specific version(s) of iPhone:
16 | //
17 | // OTHER_LDFLAGS[sdk=iphoneos4*]=$(inherited) -framework Foo
18 | // OTHER_LDFLAGS[sdk=iphonesimulator4*]=$(inherited) -framework Foo
19 | //
20 | //
21 | // How to add a compiler define:
22 | //
23 | // OTHER_CFLAGS=$(inherited) -DFOO=1
24 | //
25 | //
26 | // IMPORTANT NOTE: always use $(inherited) in your overrides
27 | //
28 |
--------------------------------------------------------------------------------
/platform/README:
--------------------------------------------------------------------------------
1 | You can place platform-specific files here in sub-folders named "android" and/or "iphone", just as you can with normal Titanium Mobile SDK projects. Any folders and files you place here will be merged with the platform-specific files in a Titanium Mobile project that uses this module.
2 |
3 | When a Titanium Mobile project that uses this module is built, the files from this platform/ folder will be treated the same as files (if any) from the Titanium Mobile project's platform/ folder.
4 |
--------------------------------------------------------------------------------
/timodule.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/titanium.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // CHANGE THESE VALUES TO REFLECT THE VERSION (AND LOCATION IF DIFFERENT)
4 | // OF YOUR TITANIUM SDK YOU'RE BUILDING FOR
5 | //
6 | //
7 | TITANIUM_SDK_VERSION = 3.2.1.GA
8 |
9 |
10 | //
11 | // THESE SHOULD BE OK GENERALLY AS-IS
12 | //
13 | TITANIUM_SDK = ~/Library/Application Support/Titanium/mobilesdk/osx/$(TITANIUM_SDK_VERSION)
14 | TITANIUM_BASE_SDK = "$(TITANIUM_SDK)/iphone/include"
15 | TITANIUM_BASE_SDK2 = "$(TITANIUM_SDK)/iphone/include/TiCore"
16 | HEADER_SEARCH_PATHS= $(TITANIUM_BASE_SDK) $(TITANIUM_BASE_SDK2)
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------