├── Changelog.md
├── DemoApp
├── DemoApp-Info.plist
├── DemoApp-Prefix.pch
├── NXAppDelegate.h
├── NXAppDelegate.m
├── NXViewController.h
├── NXViewController.m
├── en.lproj
│ ├── InfoPlist.strings
│ └── NXViewController.xib
└── main.m
├── LICENSE
├── Libraries
├── OCMock.framework
│ ├── Headers
│ ├── OCMock
│ ├── Resources
│ └── Versions
│ │ ├── A
│ │ ├── Headers
│ │ │ ├── NSNotificationCenter+OCMAdditions.h
│ │ │ ├── OCMArg.h
│ │ │ ├── OCMConstraint.h
│ │ │ ├── OCMock.h
│ │ │ ├── OCMockObject.h
│ │ │ └── OCMockRecorder.h
│ │ ├── OCMock
│ │ └── Resources
│ │ │ ├── Info.plist
│ │ │ └── en.lproj
│ │ │ └── InfoPlist.strings
│ │ └── Current
└── SVPullToRefresh
│ ├── SVPullToRefresh.h
│ └── SVPullToRefresh.m
├── Readme.md
├── UITableView+NXEmptyView.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
├── UITableView+NXEmptyView
├── UITableView+NXEmptyView-Info.plist
├── UITableView+NXEmptyView-Prefix.pch
├── UITableView+NXEmptyView.h
├── UITableView+NXEmptyView.m
└── en.lproj
│ └── InfoPlist.strings
├── UITableView+NXEmptyViewTests
├── UITableView+NXEmptyViewTests-Info.plist
├── UITableView_NXEmptyViewTests.h
├── UITableView_NXEmptyViewTests.m
└── en.lproj
│ └── InfoPlist.strings
└── UITableView-NXEmptyView.podspec
/Changelog.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | # v0.1.4
4 | - adding the empty view only once (so layouting only runs once),
5 | using `hidden` property now to trigger visibility
6 |
7 | # v0.1.3
8 | - preventing the empty view from hiding the table header view
9 |
10 | # v0.1.2
11 | - fixing issue #1 (support for pull to refresh)
12 | - adding an option to hide the seperator lines when the empty view is shown (great for transparent empty views!)
13 |
14 | # v0.1.1
15 | - fixed a bug where the empty wouldn't be resized when the table view resizes while the empty view is shown - b0c6de5
16 | - added an extension to the `UITableViewDataSource` protocol to bypass the showing of the empty view - 09564aa
17 |
18 | # v0.1.0
19 |
20 | - Initial release
21 |
--------------------------------------------------------------------------------
/DemoApp/DemoApp-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.nxtbgthng.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/DemoApp/DemoApp-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'DemoApp' target in the 'DemoApp' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_4_0
8 | #warning "This project uses features only available in iOS SDK 4.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/DemoApp/NXAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // NXAppDelegate.h
3 | // DemoApp
4 | //
5 | // Created by Ullrich Schäfer on 21.06.12.
6 | // Copyright (c) 2012 nxtbgthng.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class NXViewController;
12 |
13 | @interface NXAppDelegate : UIResponder
14 |
15 | @property (strong, nonatomic) UIWindow *window;
16 |
17 | @property (strong, nonatomic) NXViewController *viewController;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/DemoApp/NXAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // NXAppDelegate.m
3 | // DemoApp
4 | //
5 | // Created by Ullrich Schäfer on 21.06.12.
6 | // Copyright (c) 2012 nxtbgthng.com. All rights reserved.
7 | //
8 |
9 | #import "NXAppDelegate.h"
10 |
11 | #import "NXViewController.h"
12 |
13 | @implementation NXAppDelegate
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
16 | {
17 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
18 | // Override point for customization after application launch.
19 | self.viewController = [[NXViewController alloc] initWithNibName:@"NXViewController" bundle:nil];
20 | self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
21 | [self.window makeKeyAndVisible];
22 | return YES;
23 | }
24 |
25 | - (void)applicationWillResignActive:(UIApplication *)application
26 | {
27 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
28 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
29 | }
30 |
31 | - (void)applicationDidEnterBackground:(UIApplication *)application
32 | {
33 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
34 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
35 | }
36 |
37 | - (void)applicationWillEnterForeground:(UIApplication *)application
38 | {
39 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
40 | }
41 |
42 | - (void)applicationDidBecomeActive:(UIApplication *)application
43 | {
44 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
45 | }
46 |
47 | - (void)applicationWillTerminate:(UIApplication *)application
48 | {
49 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/DemoApp/NXViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // NXViewController.h
3 | // DemoApp
4 | //
5 | // Created by Ullrich Schäfer on 21.06.12.
6 | // Copyright (c) 2012 nxtbgthng.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NXViewController : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/DemoApp/NXViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // NXViewController.m
3 | // DemoApp
4 | //
5 | // Created by Ullrich Schäfer on 21.06.12.
6 | // Copyright (c) 2012 nxtbgthng.com. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "SVPullToRefresh.h"
12 |
13 | #import "NXViewController.h"
14 |
15 |
16 | @interface NXViewController ()
17 |
18 | @property (nonatomic, retain) NSArray *items;
19 | @end
20 |
21 | @implementation NXViewController
22 |
23 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
24 | {
25 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
26 | if (self) {
27 | self.items = [NSArray arrayWithObjects:@"0", @"1", nil];
28 | UIBarButtonItem *addItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
29 | target:self action:@selector(add:)];
30 | UIBarButtonItem *removeItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemUndo
31 | target:self action:@selector(remove:)];
32 | self.toolbarItems = [NSArray arrayWithObjects:addItem, removeItem, nil];
33 | }
34 | return self;
35 | }
36 |
37 | - (void)viewDidLoad;
38 | {
39 | [super viewDidLoad];
40 | self.tableView.nxEV_hideSeparatorLinesWhenShowingEmptyView = YES;
41 |
42 | Class refreshControlClass = NSClassFromString(@"UIRefreshControl");
43 | if (refreshControlClass) {
44 | id refreshControl = [[refreshControlClass alloc] init];
45 |
46 | [refreshControl addTarget:self
47 | action:@selector(refresh:)
48 | forControlEvents:UIControlEventValueChanged];
49 |
50 | [self setRefreshControl:refreshControl];
51 | } else {
52 | __block id blockSelf = self;
53 | [self.tableView addPullToRefreshWithActionHandler:^{
54 | [blockSelf refresh:nil];
55 | }];
56 | }
57 | }
58 |
59 | - (void)viewDidAppear:(BOOL)animated;
60 | {
61 | [super viewDidAppear:animated];
62 | self.navigationController.toolbarHidden = NO;
63 | }
64 |
65 |
66 | #pragma mark Actions
67 |
68 | - (IBAction)add:(id)sender;
69 | {
70 | self.items = [self.items arrayByAddingObject:[NSString stringWithFormat:@"%d", self.items.count]];
71 | }
72 |
73 | - (IBAction)remove:(id)sender
74 | {
75 | NSInteger length = fmaxf((NSInteger)self.items.count - 1, 0);
76 | self.items = [self.items subarrayWithRange:NSMakeRange(0, length)];
77 | }
78 |
79 | - (IBAction)refresh:(id)sender
80 | {
81 | if ([self respondsToSelector:@selector(refreshControl)]) {
82 | [self.refreshControl endRefreshing];
83 | }
84 |
85 | if ([self.tableView respondsToSelector:@selector(pullToRefreshView)]) {
86 | [self.tableView.pullToRefreshView stopAnimating];
87 | }
88 |
89 | if (self.items.count == 0) {
90 | [self add:nil];
91 | }
92 | }
93 |
94 |
95 | #pragma mark The DataSource
96 |
97 | - (void)setItems:(NSArray *)items;
98 | {
99 | _items = items;
100 | [self.tableView reloadData];
101 | }
102 |
103 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
104 | {
105 | return self.items.count;
106 | }
107 |
108 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
109 | {
110 | NSString *identifier = @"xx";
111 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
112 | if (!cell) {
113 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
114 | }
115 |
116 | cell.textLabel.text = [self.items objectAtIndex:indexPath.row];
117 | return cell;
118 | }
119 |
120 | @end
121 |
--------------------------------------------------------------------------------
/DemoApp/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/DemoApp/en.lproj/NXViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1536
5 | 12C60
6 | 2843
7 | 1187.34
8 | 625.00
9 |
13 |
14 | IBProxyObject
15 | IBUILabel
16 | IBUITableView
17 | IBUIView
18 |
19 |
20 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
21 |
22 |
26 |
27 |
31 |
35 |
59 |
60 |
61 | 292
62 |
63 |
64 |
65 | 290
66 | {{10, 140}, {300, 37}}
67 |
68 |
69 |
70 | _NS:9
71 | NO
72 | YES
73 | 7
74 | NO
75 | IBCocoaTouchFramework
76 | No Items
77 |
78 | 1
79 | MCAwIDAAA
80 | darkTextColor
81 |
82 |
83 | 0
84 | 10
85 | 1
86 |
87 | 2
88 | 31
89 |
90 |
91 | Helvetica-Bold
92 | 31
93 | 16
94 |
95 | NO
96 |
97 |
98 |
99 | 264
100 | {{10, 300}, {300, 63}}
101 |
102 |
103 | _NS:9
104 | NO
105 | YES
106 | 7
107 | NO
108 | IBCocoaTouchFramework
109 | VGhlcmUncyBub3RoaW5nIHRvIHNob3cgaW4gdGhlIHRhYmxlIHZpZXcsIHNvIGhlcmUncyB0aGUgZW1w
110 | dHkgdmlldy4gWW91IGNhbiBmaW5kIGl0IGluIE5YVmlld0NvbnRyb2xsZXIueGliCg
111 |
112 |
113 | 0
114 | 10
115 | 0
116 | 1
117 | 0
118 |
119 | 1
120 | 17
121 |
122 |
123 | Helvetica
124 | 17
125 | 16
126 |
127 | NO
128 | 300
129 |
130 |
131 | {320, 460}
132 |
133 |
134 |
135 | _NS:9
136 |
137 | 3
138 | MCAwAA
139 |
140 | IBCocoaTouchFramework
141 |
142 |
143 |
144 |
145 |
146 |
147 | view
148 |
149 |
150 |
151 | 17
152 |
153 |
154 |
155 | nxEV_emptyView
156 |
157 |
158 |
159 | 16
160 |
161 |
162 |
163 | dataSource
164 |
165 |
166 |
167 | 18
168 |
169 |
170 |
171 | delegate
172 |
173 |
174 |
175 | 19
176 |
177 |
178 |
179 |
180 |
181 | 0
182 |
183 |
184 |
185 |
186 |
187 | -1
188 |
189 |
190 | File's Owner
191 |
192 |
193 | -2
194 |
195 |
196 |
197 |
198 | 13
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 | 14
208 |
209 |
210 |
211 |
212 | 15
213 |
214 |
215 |
216 |
217 | 9
218 |
219 |
220 |
221 |
222 |
223 |
224 | NXViewController
225 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
226 | UIResponder
227 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
228 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
229 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
230 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
231 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
232 |
233 |
234 |
235 |
236 |
237 | 19
238 |
239 |
240 |
241 |
242 | NXViewController
243 | UITableViewController
244 |
245 | id
246 | id
247 | id
248 |
249 |
250 |
251 | add:
252 | id
253 |
254 |
255 | refresh:
256 | id
257 |
258 |
259 | remove:
260 | id
261 |
262 |
263 |
264 | IBProjectSource
265 | ./Classes/NXViewController.h
266 |
267 |
268 |
269 | UITableView
270 |
271 | nxEV_emptyView
272 | UIView
273 |
274 |
275 | nxEV_emptyView
276 |
277 | nxEV_emptyView
278 | UIView
279 |
280 |
281 |
282 | IBProjectSource
283 | ./Classes/UITableView.h
284 |
285 |
286 |
287 |
288 | 0
289 | IBCocoaTouchFramework
290 |
291 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
292 |
293 |
294 | YES
295 | 3
296 | 1929
297 |
298 |
299 |
--------------------------------------------------------------------------------
/DemoApp/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // DemoApp
4 | //
5 | // Created by Ullrich Schäfer on 21.06.12.
6 | // Copyright (c) 2012 nxtbgthng.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "NXAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([NXAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012, nxtbgthng GmbH
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | * Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | * Neither the name of the nxtbgthng GmbH nor the
12 | names of its contributors may be used to endorse or promote products
13 | derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 | DISCLAIMED. IN NO EVENT SHALL nxtbgthng GmbH BE LIABLE FOR ANY
19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 |
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Headers:
--------------------------------------------------------------------------------
1 | Versions/Current/Headers
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/OCMock:
--------------------------------------------------------------------------------
1 | Versions/Current/OCMock
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Resources:
--------------------------------------------------------------------------------
1 | Versions/Current/Resources
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/A/Headers/NSNotificationCenter+OCMAdditions.h:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------------------
2 | // $Id$
3 | // Copyright (c) 2009 by Mulle Kybernetik. See License file for details.
4 | //---------------------------------------------------------------------------------------
5 |
6 | #import
7 |
8 | @class OCMockObserver;
9 |
10 |
11 | @interface NSNotificationCenter(OCMAdditions)
12 |
13 | - (void)addMockObserver:(OCMockObserver *)notificationObserver name:(NSString *)notificationName object:(id)notificationSender;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/A/Headers/OCMArg.h:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------------------
2 | // $Id$
3 | // Copyright (c) 2009-2013 by Mulle Kybernetik. See License file for details.
4 | //---------------------------------------------------------------------------------------
5 |
6 | #import
7 |
8 | @interface OCMArg : NSObject
9 |
10 | // constraining arguments
11 |
12 | + (id)any;
13 | + (SEL)anySelector;
14 | + (void *)anyPointer;
15 | + (id __autoreleasing *)anyObjectRef;
16 | + (id)isNil;
17 | + (id)isNotNil;
18 | + (id)isNotEqual:(id)value;
19 | + (id)checkWithSelector:(SEL)selector onObject:(id)anObject;
20 | #if NS_BLOCKS_AVAILABLE
21 | + (id)checkWithBlock:(BOOL (^)(id obj))block;
22 | #endif
23 |
24 | // manipulating arguments
25 |
26 | + (id *)setTo:(id)value;
27 | + (void *)setToValue:(NSValue *)value;
28 |
29 | // internal use only
30 |
31 | + (id)resolveSpecialValues:(NSValue *)value;
32 |
33 | @end
34 |
35 | #define OCMOCK_ANY [OCMArg any]
36 |
37 | #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
38 | #define OCMOCK_VALUE(variable) \
39 | ({ __typeof__(variable) __v = (variable); [NSValue value:&__v withObjCType:@encode(__typeof__(__v))]; })
40 | #else
41 | #define OCMOCK_VALUE(variable) [NSValue value:&variable withObjCType:@encode(__typeof__(variable))]
42 | #endif
43 |
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/A/Headers/OCMConstraint.h:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------------------
2 | // $Id$
3 | // Copyright (c) 2007-2010 by Mulle Kybernetik. See License file for details.
4 | //---------------------------------------------------------------------------------------
5 |
6 | #import
7 |
8 |
9 | @interface OCMConstraint : NSObject
10 |
11 | + (id)constraint;
12 | - (BOOL)evaluate:(id)value;
13 |
14 | // if you are looking for any, isNil, etc, they have moved to OCMArg
15 |
16 | // try to use [OCMArg checkWith...] instead of the constraintWith... methods below
17 |
18 | + (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject;
19 | + (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject withValue:(id)aValue;
20 |
21 |
22 | @end
23 |
24 | @interface OCMAnyConstraint : OCMConstraint
25 | @end
26 |
27 | @interface OCMIsNilConstraint : OCMConstraint
28 | @end
29 |
30 | @interface OCMIsNotNilConstraint : OCMConstraint
31 | @end
32 |
33 | @interface OCMIsNotEqualConstraint : OCMConstraint
34 | {
35 | @public
36 | id testValue;
37 | }
38 |
39 | @end
40 |
41 | @interface OCMInvocationConstraint : OCMConstraint
42 | {
43 | @public
44 | NSInvocation *invocation;
45 | }
46 |
47 | @end
48 |
49 | #if NS_BLOCKS_AVAILABLE
50 |
51 | @interface OCMBlockConstraint : OCMConstraint
52 | {
53 | BOOL (^block)(id);
54 | }
55 |
56 | - (id)initWithConstraintBlock:(BOOL (^)(id))block;
57 |
58 | @end
59 |
60 | #endif
61 |
62 |
63 | #define CONSTRAINT(aSelector) [OCMConstraint constraintWithSelector:aSelector onObject:self]
64 | #define CONSTRAINTV(aSelector, aValue) [OCMConstraint constraintWithSelector:aSelector onObject:self withValue:(aValue)]
65 |
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/A/Headers/OCMock.h:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------------------
2 | // $Id$
3 | // Copyright (c) 2004-2008 by Mulle Kybernetik. See License file for details.
4 | //---------------------------------------------------------------------------------------
5 |
6 | #import
7 | #import
8 | #import
9 | #import
10 | #import
11 |
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/A/Headers/OCMockObject.h:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------------------
2 | // $Id$
3 | // Copyright (c) 2004-2008 by Mulle Kybernetik. See License file for details.
4 | //---------------------------------------------------------------------------------------
5 |
6 | #import
7 |
8 | @interface OCMockObject : NSProxy
9 | {
10 | BOOL isNice;
11 | BOOL expectationOrderMatters;
12 | NSMutableArray *recorders;
13 | NSMutableArray *expectations;
14 | NSMutableArray *rejections;
15 | NSMutableArray *exceptions;
16 | }
17 |
18 | + (id)mockForClass:(Class)aClass;
19 | + (id)mockForProtocol:(Protocol *)aProtocol;
20 | + (id)partialMockForObject:(NSObject *)anObject;
21 |
22 | + (id)niceMockForClass:(Class)aClass;
23 | + (id)niceMockForProtocol:(Protocol *)aProtocol;
24 |
25 | + (id)observerMock;
26 |
27 | - (id)init;
28 |
29 | - (void)setExpectationOrderMatters:(BOOL)flag;
30 |
31 | - (id)stub;
32 | - (id)expect;
33 | - (id)reject;
34 |
35 | - (void)verify;
36 | - (void)verifyWithDelay:(NSTimeInterval)delay;
37 |
38 | - (void)stopMocking;
39 |
40 | // internal use only
41 |
42 | - (id)getNewRecorder;
43 | - (BOOL)handleInvocation:(NSInvocation *)anInvocation;
44 | - (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation;
45 | - (BOOL)handleSelector:(SEL)sel;
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/A/Headers/OCMockRecorder.h:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------------------
2 | // $Id$
3 | // Copyright (c) 2004-2013 by Mulle Kybernetik. See License file for details.
4 | //---------------------------------------------------------------------------------------
5 |
6 | #import
7 |
8 | @interface OCMockRecorder : NSProxy
9 | {
10 | id signatureResolver;
11 | BOOL recordedAsClassMethod;
12 | BOOL ignoreNonObjectArgs;
13 | NSInvocation *recordedInvocation;
14 | NSMutableArray *invocationHandlers;
15 | }
16 |
17 | - (id)initWithSignatureResolver:(id)anObject;
18 |
19 | - (BOOL)matchesSelector:(SEL)sel;
20 | - (BOOL)matchesInvocation:(NSInvocation *)anInvocation;
21 | - (void)releaseInvocation;
22 |
23 | - (id)andReturn:(id)anObject;
24 | - (id)andReturnValue:(NSValue *)aValue;
25 | - (id)andThrow:(NSException *)anException;
26 | - (id)andPost:(NSNotification *)aNotification;
27 | - (id)andCall:(SEL)selector onObject:(id)anObject;
28 | #if NS_BLOCKS_AVAILABLE
29 | - (id)andDo:(void (^)(NSInvocation *))block;
30 | #endif
31 | - (id)andForwardToRealObject;
32 |
33 | - (id)classMethod;
34 | - (id)ignoringNonObjectArgs;
35 |
36 | - (NSArray *)invocationHandlers;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/A/OCMock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nxtbgthng/UITableView-NXEmptyView/6baf75b6f0f7752c7747678d2bc81cd603648fe2/Libraries/OCMock.framework/Versions/A/OCMock
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/A/Resources/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 13C64
7 | CFBundleDevelopmentRegion
8 | English
9 | CFBundleExecutable
10 | OCMock
11 | CFBundleIdentifier
12 | com.mulle-kybernetik.OCMock
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | OCMock
17 | CFBundlePackageType
18 | FMWK
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | DTCompiler
26 | com.apple.compilers.llvm.clang.1_0
27 | DTPlatformBuild
28 | 5B130a
29 | DTPlatformVersion
30 | GM
31 | DTSDKBuild
32 | 13C64
33 | DTSDKName
34 | macosx10.9
35 | DTXcode
36 | 0510
37 | DTXcodeBuild
38 | 5B130a
39 | NSHumanReadableCopyright
40 | Copyright © 2004-2013 Mulle Kybernetik.
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/A/Resources/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nxtbgthng/UITableView-NXEmptyView/6baf75b6f0f7752c7747678d2bc81cd603648fe2/Libraries/OCMock.framework/Versions/A/Resources/en.lproj/InfoPlist.strings
--------------------------------------------------------------------------------
/Libraries/OCMock.framework/Versions/Current:
--------------------------------------------------------------------------------
1 | A
--------------------------------------------------------------------------------
/Libraries/SVPullToRefresh/SVPullToRefresh.h:
--------------------------------------------------------------------------------
1 | //
2 | // SVPullToRefresh.h
3 | //
4 | // Created by Sam Vermette on 23.04.12.
5 | // Copyright (c) 2012 samvermette.com. All rights reserved.
6 | //
7 | // https://github.com/samvermette/SVPullToRefresh
8 | //
9 |
10 | #import
11 |
12 | enum {
13 | SVPullToRefreshStateHidden = 1,
14 | SVPullToRefreshStateVisible,
15 | SVPullToRefreshStateTriggered,
16 | SVPullToRefreshStateLoading
17 | };
18 |
19 | typedef NSUInteger SVPullToRefreshState;
20 |
21 | @interface SVPullToRefresh : UIView
22 |
23 | @property (nonatomic, strong) UIColor *arrowColor;
24 | @property (nonatomic, strong) UIColor *textColor;
25 | @property (nonatomic, readwrite) UIActivityIndicatorViewStyle activityIndicatorViewStyle;
26 |
27 | @property (nonatomic, strong) UILabel *dateLabel;
28 | @property (nonatomic, strong) NSDate *lastUpdatedDate;
29 | @property (nonatomic, strong) NSDateFormatter *dateFormatter;
30 |
31 | @property (nonatomic, readonly) SVPullToRefreshState state;
32 |
33 | - (void)triggerRefresh;
34 | - (void)startAnimating;
35 | - (void)stopAnimating;
36 |
37 | @end
38 |
39 |
40 | // extends UIScrollView
41 |
42 | @interface UIScrollView (SVPullToRefresh)
43 |
44 | - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler;
45 | - (void)addInfiniteScrollingWithActionHandler:(void (^)(void))actionHandler;
46 |
47 | @property (nonatomic, strong) SVPullToRefresh *pullToRefreshView;
48 | @property (nonatomic, strong) SVPullToRefresh *infiniteScrollingView;
49 |
50 | @property (nonatomic, assign) BOOL showsPullToRefresh;
51 | @property (nonatomic, assign) BOOL showsInfiniteScrolling;
52 |
53 | @end
--------------------------------------------------------------------------------
/Libraries/SVPullToRefresh/SVPullToRefresh.m:
--------------------------------------------------------------------------------
1 | //
2 | // SVPullToRefresh.m
3 | //
4 | // Created by Sam Vermette on 23.04.12.
5 | // Copyright (c) 2012 samvermette.com. All rights reserved.
6 | //
7 | // https://github.com/samvermette/SVPullToRefresh
8 | //
9 |
10 | #import
11 | #import "SVPullToRefresh.h"
12 |
13 | static CGFloat const SVPullToRefreshViewHeight = 60;
14 |
15 | @interface SVPullToRefreshArrow : UIView
16 | @property (nonatomic, strong) UIColor *arrowColor;
17 | @end
18 |
19 |
20 | @interface SVPullToRefresh ()
21 |
22 | - (id)initWithScrollView:(UIScrollView*)scrollView;
23 | - (void)rotateArrow:(float)degrees hide:(BOOL)hide;
24 | - (void)setScrollViewContentInset:(UIEdgeInsets)contentInset;
25 | - (void)scrollViewDidScroll:(CGPoint)contentOffset;
26 |
27 | - (void)startObservingScrollView;
28 | - (void)stopObservingScrollView;
29 |
30 | @property (nonatomic, copy) void (^pullToRefreshActionHandler)(void);
31 | @property (nonatomic, copy) void (^infiniteScrollingActionHandler)(void);
32 |
33 | @property (nonatomic, strong) SVPullToRefreshArrow *arrow;
34 | @property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView;
35 | @property (nonatomic, strong) UILabel *titleLabel;
36 |
37 |
38 | @property (nonatomic, unsafe_unretained) UIScrollView *scrollView;
39 | @property (nonatomic, readwrite) UIEdgeInsets originalScrollViewContentInset;
40 | @property (nonatomic, strong) UIView *originalTableFooterView;
41 |
42 | @property (nonatomic, assign) BOOL showsPullToRefresh;
43 | @property (nonatomic, assign) BOOL showsInfiniteScrolling;
44 | @property (nonatomic, assign) BOOL isObservingScrollView;
45 |
46 | @end
47 |
48 |
49 |
50 | @implementation SVPullToRefresh
51 |
52 | // public properties
53 | @synthesize pullToRefreshActionHandler, infiniteScrollingActionHandler, arrowColor, textColor, activityIndicatorViewStyle, lastUpdatedDate, dateFormatter;
54 |
55 | @synthesize state = _state;
56 | @synthesize scrollView = _scrollView;
57 | @synthesize arrow, activityIndicatorView, titleLabel, dateLabel, originalScrollViewContentInset, originalTableFooterView, showsPullToRefresh, showsInfiniteScrolling, isObservingScrollView;
58 |
59 | - (void)dealloc {
60 | [self stopObservingScrollView];
61 | }
62 |
63 | - (id)initWithScrollView:(UIScrollView *)scrollView {
64 | self = [super initWithFrame:CGRectZero];
65 | self.scrollView = scrollView;
66 |
67 | // default styling values
68 | self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
69 | self.textColor = [UIColor darkGrayColor];
70 |
71 | self.originalScrollViewContentInset = self.scrollView.contentInset;
72 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
73 |
74 | return self;
75 | }
76 |
77 | - (void)willMoveToSuperview:(UIView *)newSuperview {
78 | if(newSuperview == self.scrollView)
79 | [self startObservingScrollView];
80 | else if(newSuperview == nil)
81 | [self stopObservingScrollView];
82 | }
83 |
84 | - (void)layoutSubviews {
85 | CGFloat remainingWidth = self.superview.bounds.size.width-200;
86 | float position = 0.50;
87 |
88 | CGRect titleFrame = titleLabel.frame;
89 | titleFrame.origin.x = ceil(remainingWidth*position+44);
90 | titleLabel.frame = titleFrame;
91 |
92 | CGRect dateFrame = dateLabel.frame;
93 | dateFrame.origin.x = titleFrame.origin.x;
94 | dateLabel.frame = dateFrame;
95 |
96 | CGRect arrowFrame = arrow.frame;
97 | arrowFrame.origin.x = ceil(remainingWidth*position);
98 | arrow.frame = arrowFrame;
99 |
100 | if(infiniteScrollingActionHandler) {
101 | self.activityIndicatorView.center = CGPointMake(round(self.bounds.size.width/2), round(self.bounds.size.height/2));
102 | } else
103 | self.activityIndicatorView.center = self.arrow.center;
104 |
105 | }
106 |
107 | #pragma mark - Getters
108 |
109 | - (SVPullToRefreshArrow *)arrow {
110 | if(!arrow && pullToRefreshActionHandler) {
111 | self.arrow = [[SVPullToRefreshArrow alloc]initWithFrame:CGRectMake(0, 6, 22, 48)];
112 | arrow.backgroundColor = [UIColor clearColor];
113 |
114 | // assign a different default color for arrow
115 | // arrow.arrowColor = [UIColor blueColor];
116 | }
117 | return arrow;
118 | }
119 |
120 | - (UIActivityIndicatorView *)activityIndicatorView {
121 | if(!activityIndicatorView) {
122 | activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
123 | activityIndicatorView.hidesWhenStopped = YES;
124 | [self addSubview:activityIndicatorView];
125 | }
126 | return activityIndicatorView;
127 | }
128 |
129 | - (UILabel *)dateLabel {
130 | if(!dateLabel && pullToRefreshActionHandler) {
131 | dateLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 28, 180, 20)];
132 | dateLabel.font = [UIFont systemFontOfSize:12];
133 | dateLabel.backgroundColor = [UIColor clearColor];
134 | dateLabel.textColor = textColor;
135 | [self addSubview:dateLabel];
136 |
137 | CGRect titleFrame = titleLabel.frame;
138 | titleFrame.origin.y = 12;
139 | titleLabel.frame = titleFrame;
140 | }
141 | return dateLabel;
142 | }
143 |
144 | - (NSDateFormatter *)dateFormatter {
145 | if(!dateFormatter) {
146 | dateFormatter = [[NSDateFormatter alloc] init];
147 | [dateFormatter setDateStyle:NSDateFormatterShortStyle];
148 | [dateFormatter setTimeStyle:NSDateFormatterShortStyle];
149 | dateFormatter.locale = [NSLocale currentLocale];
150 | }
151 | return dateFormatter;
152 | }
153 |
154 | - (UIEdgeInsets)originalScrollViewContentInset {
155 | return UIEdgeInsetsMake(originalScrollViewContentInset.top, self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right);
156 | }
157 |
158 | #pragma mark - Setters
159 |
160 | - (void)setPullToRefreshActionHandler:(void (^)(void))actionHandler {
161 | pullToRefreshActionHandler = [actionHandler copy];
162 | [_scrollView addSubview:self];
163 | self.showsPullToRefresh = YES;
164 |
165 | // If the titleLabel is added before, there is no need to add again.
166 | if (self.titleLabel == nil) {
167 | self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 150, 20)];
168 | titleLabel.text = NSLocalizedString(@"Pull to refresh...",);
169 | titleLabel.font = [UIFont boldSystemFontOfSize:14];
170 | titleLabel.backgroundColor = [UIColor clearColor];
171 | titleLabel.textColor = textColor;
172 | [self addSubview:titleLabel];
173 | }
174 |
175 | [self addSubview:self.arrow];
176 |
177 | self.state = SVPullToRefreshStateHidden;
178 | self.frame = CGRectMake(0, -SVPullToRefreshViewHeight, self.scrollView.bounds.size.width, SVPullToRefreshViewHeight);
179 | }
180 |
181 | - (void)setInfiniteScrollingActionHandler:(void (^)(void))actionHandler {
182 | self.originalTableFooterView = [(UITableView*)self.scrollView tableFooterView];
183 | infiniteScrollingActionHandler = [actionHandler copy];
184 | self.showsInfiniteScrolling = YES;
185 | self.frame = CGRectMake(0, 0, self.scrollView.bounds.size.width, SVPullToRefreshViewHeight);
186 | [(UITableView*)self.scrollView setTableFooterView:self];
187 | self.state = SVPullToRefreshStateHidden;
188 | [self layoutSubviews];
189 | }
190 |
191 | - (void)setArrowColor:(UIColor *)newArrowColor {
192 | self.arrow.arrowColor = newArrowColor; // pass through
193 | [self.arrow setNeedsDisplay];
194 | }
195 |
196 | - (UIColor *)arrowColor {
197 | return self.arrow.arrowColor; // pass through
198 | }
199 |
200 | - (void)setTextColor:(UIColor *)newTextColor {
201 | textColor = newTextColor;
202 | titleLabel.textColor = newTextColor;
203 | dateLabel.textColor = newTextColor;
204 | }
205 |
206 | - (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)viewStyle {
207 | self.activityIndicatorView.activityIndicatorViewStyle = viewStyle;
208 | }
209 |
210 | - (void)setScrollViewContentInset:(UIEdgeInsets)contentInset {
211 | [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState animations:^{
212 | self.scrollView.contentInset = contentInset;
213 | } completion:^(BOOL finished) {
214 | if(self.state == SVPullToRefreshStateHidden && contentInset.top == self.originalScrollViewContentInset.top)
215 | [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
216 | arrow.alpha = 0;
217 | } completion:NULL];
218 | }];
219 | }
220 |
221 | - (void)setLastUpdatedDate:(NSDate *)newLastUpdatedDate {
222 | self.dateLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Last Updated: %@",), newLastUpdatedDate?[self.dateFormatter stringFromDate:newLastUpdatedDate]:NSLocalizedString(@"Never",)];
223 | }
224 |
225 | - (void)setDateFormatter:(NSDateFormatter *)newDateFormatter {
226 | dateFormatter = newDateFormatter;
227 | self.dateLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Last Updated: %@",), self.lastUpdatedDate?[newDateFormatter stringFromDate:self.lastUpdatedDate]:NSLocalizedString(@"Never",)];
228 | }
229 |
230 | - (void)setShowsInfiniteScrolling:(BOOL)show {
231 | showsInfiniteScrolling = show;
232 | if(!show)
233 | [(UITableView*)self.scrollView setTableFooterView:self.originalTableFooterView];
234 | else
235 | [(UITableView*)self.scrollView setTableFooterView:self];
236 | }
237 |
238 | #pragma mark -
239 |
240 | - (void)startObservingScrollView {
241 | if (self.isObservingScrollView)
242 | return;
243 |
244 | [self.scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
245 | [self.scrollView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
246 | self.isObservingScrollView = YES;
247 | }
248 |
249 | - (void)stopObservingScrollView {
250 | if(!self.isObservingScrollView)
251 | return;
252 |
253 | [self.scrollView removeObserver:self forKeyPath:@"contentOffset"];
254 | [self.scrollView removeObserver:self forKeyPath:@"frame"];
255 | self.isObservingScrollView = NO;
256 | }
257 |
258 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
259 | if([keyPath isEqualToString:@"contentOffset"])
260 | [self scrollViewDidScroll:[[change valueForKey:NSKeyValueChangeNewKey] CGPointValue]];
261 | else if([keyPath isEqualToString:@"frame"])
262 | [self layoutSubviews];
263 | }
264 |
265 | - (void)scrollViewDidScroll:(CGPoint)contentOffset {
266 | if(pullToRefreshActionHandler) {
267 | if (self.state == SVPullToRefreshStateLoading) {
268 | CGFloat offset = MAX(self.scrollView.contentOffset.y * -1, 0);
269 | offset = MIN(offset, self.originalScrollViewContentInset.top + SVPullToRefreshViewHeight);
270 | self.scrollView.contentInset = UIEdgeInsetsMake(offset, 0.0f, 0.0f, 0.0f);
271 | } else {
272 | CGFloat scrollOffsetThreshold = self.frame.origin.y-self.originalScrollViewContentInset.top;
273 |
274 | if(!self.scrollView.isDragging && self.state == SVPullToRefreshStateTriggered)
275 | self.state = SVPullToRefreshStateLoading;
276 | else if(contentOffset.y > scrollOffsetThreshold && contentOffset.y < -self.originalScrollViewContentInset.top && self.scrollView.isDragging && self.state != SVPullToRefreshStateLoading)
277 | self.state = SVPullToRefreshStateVisible;
278 | else if(contentOffset.y < scrollOffsetThreshold && self.scrollView.isDragging && self.state == SVPullToRefreshStateVisible)
279 | self.state = SVPullToRefreshStateTriggered;
280 | else if(contentOffset.y >= -self.originalScrollViewContentInset.top && self.state != SVPullToRefreshStateHidden)
281 | self.state = SVPullToRefreshStateHidden;
282 | }
283 | }
284 | else if(infiniteScrollingActionHandler) {
285 | CGFloat scrollOffsetThreshold = self.scrollView.contentSize.height-self.scrollView.bounds.size.height-self.originalScrollViewContentInset.top;
286 |
287 | if(contentOffset.y > MAX(scrollOffsetThreshold, self.scrollView.bounds.size.height-self.scrollView.contentSize.height) && self.state == SVPullToRefreshStateHidden)
288 | self.state = SVPullToRefreshStateLoading;
289 | else if(contentOffset.y < scrollOffsetThreshold)
290 | self.state = SVPullToRefreshStateHidden;
291 | }
292 | }
293 |
294 | - (void)triggerRefresh {
295 | self.state = SVPullToRefreshStateLoading;
296 | [self.scrollView setContentOffset:CGPointMake(0, -SVPullToRefreshViewHeight) animated:YES];
297 | }
298 |
299 | - (void)startAnimating{
300 | _state = SVPullToRefreshStateLoading;
301 |
302 | titleLabel.text = NSLocalizedString(@"Loading...",);
303 | [self.activityIndicatorView startAnimating];
304 | UIEdgeInsets newInsets = self.originalScrollViewContentInset;
305 | newInsets.top = self.frame.origin.y*-1+self.originalScrollViewContentInset.top;
306 | newInsets.bottom = self.scrollView.contentInset.bottom;
307 | [self setScrollViewContentInset:newInsets];
308 | [self.scrollView setContentOffset:CGPointMake(0, -self.frame.size.height) animated:NO];
309 | [self rotateArrow:0 hide:YES];
310 | }
311 |
312 | - (void)stopAnimating {
313 | self.state = SVPullToRefreshStateHidden;
314 | }
315 |
316 | - (void)setState:(SVPullToRefreshState)newState {
317 |
318 | if(pullToRefreshActionHandler && !self.showsPullToRefresh && !self.activityIndicatorView.isAnimating) {
319 | titleLabel.text = NSLocalizedString(@"",);
320 | [self.activityIndicatorView stopAnimating];
321 | [self setScrollViewContentInset:self.originalScrollViewContentInset];
322 | [self rotateArrow:0 hide:YES];
323 | return;
324 | }
325 |
326 | if(infiniteScrollingActionHandler && !self.showsInfiniteScrolling)
327 | return;
328 |
329 | if(_state == newState)
330 | return;
331 |
332 | _state = newState;
333 |
334 | if(pullToRefreshActionHandler) {
335 | switch (newState) {
336 | case SVPullToRefreshStateHidden:
337 | titleLabel.text = NSLocalizedString(@"Pull to refresh...",);
338 | [self.activityIndicatorView stopAnimating];
339 | [self setScrollViewContentInset:self.originalScrollViewContentInset];
340 | [self rotateArrow:0 hide:NO];
341 | break;
342 |
343 | case SVPullToRefreshStateVisible:
344 | titleLabel.text = NSLocalizedString(@"Pull to refresh...",);
345 | arrow.alpha = 1;
346 | [self.activityIndicatorView stopAnimating];
347 | [self setScrollViewContentInset:self.originalScrollViewContentInset];
348 | [self rotateArrow:0 hide:NO];
349 | break;
350 |
351 | case SVPullToRefreshStateTriggered:
352 | titleLabel.text = NSLocalizedString(@"Release to refresh...",);
353 | [self rotateArrow:M_PI hide:NO];
354 | break;
355 |
356 | case SVPullToRefreshStateLoading:
357 | [self startAnimating];
358 | pullToRefreshActionHandler();
359 | break;
360 | }
361 | }
362 | else if(infiniteScrollingActionHandler) {
363 | switch (newState) {
364 | case SVPullToRefreshStateHidden:
365 | [self.activityIndicatorView stopAnimating];
366 | break;
367 |
368 | case SVPullToRefreshStateLoading:
369 | [self.activityIndicatorView startAnimating];
370 | infiniteScrollingActionHandler();
371 | break;
372 | }
373 | }
374 | }
375 |
376 | - (void)rotateArrow:(float)degrees hide:(BOOL)hide {
377 | [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
378 | self.arrow.layer.transform = CATransform3DMakeRotation(degrees, 0, 0, 1);
379 | self.arrow.layer.opacity = !hide;
380 | //[self.arrow setNeedsDisplay];//ios 4
381 | } completion:NULL];
382 | }
383 |
384 | @end
385 |
386 |
387 | #pragma mark - UIScrollView (SVPullToRefresh)
388 | #import
389 |
390 | static char UIScrollViewPullToRefreshView;
391 | static char UIScrollViewInfiniteScrollingView;
392 |
393 | @implementation UIScrollView (SVPullToRefresh)
394 |
395 | @dynamic pullToRefreshView, showsPullToRefresh, infiniteScrollingView, showsInfiniteScrolling;
396 |
397 | - (void)willMoveToSuperview:(UIView *)newSuperview {
398 | if(!newSuperview) {
399 | [self.pullToRefreshView removeFromSuperview];
400 | self.pullToRefreshView = nil;
401 |
402 | [self.infiniteScrollingView removeFromSuperview];
403 | self.infiniteScrollingView = nil;
404 | }
405 | }
406 |
407 | - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler {
408 | self.pullToRefreshView.pullToRefreshActionHandler = actionHandler;
409 | }
410 |
411 | - (void)addInfiniteScrollingWithActionHandler:(void (^)(void))actionHandler {
412 | self.infiniteScrollingView.infiniteScrollingActionHandler = actionHandler;
413 | }
414 |
415 | - (void)setPullToRefreshView:(SVPullToRefresh *)pullToRefreshView {
416 | [self willChangeValueForKey:@"pullToRefreshView"];
417 | objc_setAssociatedObject(self, &UIScrollViewPullToRefreshView,
418 | pullToRefreshView,
419 | OBJC_ASSOCIATION_RETAIN);
420 | [self didChangeValueForKey:@"pullToRefreshView"];
421 | }
422 |
423 | - (void)setInfiniteScrollingView:(SVPullToRefresh *)pullToRefreshView {
424 | [self willChangeValueForKey:@"infiniteScrollingView"];
425 | objc_setAssociatedObject(self, &UIScrollViewInfiniteScrollingView,
426 | pullToRefreshView,
427 | OBJC_ASSOCIATION_RETAIN);
428 | [self didChangeValueForKey:@"infiniteScrollingView"];
429 | }
430 |
431 | - (SVPullToRefresh *)pullToRefreshView {
432 | SVPullToRefresh *pullToRefreshView = objc_getAssociatedObject(self, &UIScrollViewPullToRefreshView);
433 | if(!pullToRefreshView) {
434 | pullToRefreshView = [[SVPullToRefresh alloc] initWithScrollView:self];
435 | self.pullToRefreshView = pullToRefreshView;
436 | }
437 | return pullToRefreshView;
438 | }
439 |
440 | - (void)setShowsPullToRefresh:(BOOL)showsPullToRefresh {
441 | self.pullToRefreshView.showsPullToRefresh = showsPullToRefresh;
442 | }
443 |
444 | - (BOOL)showsPullToRefresh {
445 | return self.pullToRefreshView.showsPullToRefresh;
446 | }
447 |
448 | - (SVPullToRefresh *)infiniteScrollingView {
449 | SVPullToRefresh *infiniteScrollingView = objc_getAssociatedObject(self, &UIScrollViewInfiniteScrollingView);
450 | if(!infiniteScrollingView) {
451 | infiniteScrollingView = [[SVPullToRefresh alloc] initWithScrollView:self];
452 | self.infiniteScrollingView = infiniteScrollingView;
453 | }
454 | return infiniteScrollingView;
455 | }
456 |
457 | - (void)setShowsInfiniteScrolling:(BOOL)showsInfiniteScrolling {
458 | self.infiniteScrollingView.showsInfiniteScrolling = showsInfiniteScrolling;
459 | }
460 |
461 | - (BOOL)showsInfiniteScrolling {
462 | return self.infiniteScrollingView.showsInfiniteScrolling;
463 | }
464 |
465 | @end
466 |
467 |
468 | #pragma mark - SVPullToRefreshArrow
469 |
470 | @implementation SVPullToRefreshArrow
471 | @synthesize arrowColor;
472 |
473 | - (UIColor *)arrowColor {
474 | if (arrowColor) return arrowColor;
475 | return [UIColor grayColor]; // default Color
476 | }
477 |
478 | - (void)drawRect:(CGRect)rect {
479 | CGContextRef c = UIGraphicsGetCurrentContext();
480 |
481 | // the rects above the arrow
482 | CGContextAddRect(c, CGRectMake(5, 0, 12, 4)); // to-do: use dynamic points
483 | CGContextAddRect(c, CGRectMake(5, 6, 12, 4)); // currently fixed size: 22 x 48pt
484 | CGContextAddRect(c, CGRectMake(5, 12, 12, 4));
485 | CGContextAddRect(c, CGRectMake(5, 18, 12, 4));
486 | CGContextAddRect(c, CGRectMake(5, 24, 12, 4));
487 | CGContextAddRect(c, CGRectMake(5, 30, 12, 4));
488 |
489 | // the arrow
490 | CGContextMoveToPoint(c, 0, 34);
491 | CGContextAddLineToPoint(c, 11, 48);
492 | CGContextAddLineToPoint(c, 22, 34);
493 | CGContextAddLineToPoint(c, 0, 34);
494 | CGContextClosePath(c);
495 |
496 | CGContextSaveGState(c);
497 | CGContextClip(c);
498 |
499 | // Gradient Declaration
500 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
501 | CGFloat alphaGradientLocations[] = {0, 0.8};
502 |
503 | CGGradientRef alphaGradient = nil;
504 | if([[[UIDevice currentDevice] systemVersion]floatValue] >= 5){
505 | NSArray* alphaGradientColors = [NSArray arrayWithObjects:
506 | (id)[self.arrowColor colorWithAlphaComponent:0].CGColor,
507 | (id)[self.arrowColor colorWithAlphaComponent:1].CGColor,
508 | nil];
509 | alphaGradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)alphaGradientColors, alphaGradientLocations);
510 | }else{
511 | const CGFloat * components = CGColorGetComponents([self.arrowColor CGColor]);
512 | int numComponents = CGColorGetNumberOfComponents([self.arrowColor CGColor]);
513 | CGFloat colors[8];
514 | switch(numComponents){
515 | case 2:{
516 | colors[0] = colors[4] = components[0];
517 | colors[1] = colors[5] = components[0];
518 | colors[2] = colors[6] = components[0];
519 | break;
520 | }
521 | case 4:{
522 | colors[0] = colors[4] = components[0];
523 | colors[1] = colors[5] = components[1];
524 | colors[2] = colors[6] = components[2];
525 | break;
526 | }
527 | }
528 | colors[3] = 0;
529 | colors[7] = 1;
530 | alphaGradient = CGGradientCreateWithColorComponents(colorSpace,colors,alphaGradientLocations,2);
531 | }
532 |
533 |
534 | CGContextDrawLinearGradient(c, alphaGradient, CGPointZero, CGPointMake(0, rect.size.height), 0);
535 |
536 | CGContextRestoreGState(c);
537 |
538 | CGGradientRelease(alphaGradient);
539 | CGColorSpaceRelease(colorSpace);
540 | }
541 | @end
542 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # NXEmptyView for UITableView
2 |
3 | ## What is this?
4 |
5 | ... a category that dynamically shows an _empty view_ when there are no entries in your table view.
6 |
7 | ## Behavior
8 |
9 | The empty view will be displayed whenever the table view has no cells in any section. Of course only if a view has been set via `nxEV_emptyView`.
10 | Whenever the table view is reloaded or layouted the empty view gets updated.
11 |
12 | The frame of the empty view is updated to the bounds of the table view, so make sure it layouts nicely for all the orientations and screen sizes (iPhone 5, yay) that you're targeting.
13 |
14 | ### Bypassing the Empty View
15 |
16 | There might be scenarios in which you don't want the empty view to appear. For example when the content of the list has not yet been loaded and you don't want to scream at the user that there's none just because it has not yet been loaded.
17 |
18 | In that case you can let your table view datasource implement the `UITableViewNXEmptyViewDataSource` protocol and return `NO` in `-tableViewShouldBypassNXEmptyView:`. Whenever this value changes do a `-[UITableView reloadData]` to update the empty view.
19 |
20 | ## Install
21 |
22 | ### Via Cocoapods
23 |
24 | Add this to your Podfile
25 |
26 | pod 'UITableView-NXEmptyView'
27 |
28 | In your table view do:
29 |
30 | - `#import `
31 | - Set the `nxEV_emptyView` property of the table view with the view you want to be displayed when the table is empty.
32 | You can use the Interface Builder to do so as well.
33 |
34 | ## Contribute
35 |
36 | Contributions are highly welcomed!
37 |
38 | - Fork the repo
39 | - Add your contribution
40 | - Add a test for it if necessary
41 | - Send us a [pull request](https://github.com/nxtbgthng/UITableView-NXEmptyView/pull/new/master) describing your changes
42 | - Receive virtual high fives! :hand:
43 |
44 | Bonus points for feature branches :sunglasses:
45 |
46 | ### Contributors
47 |
48 | - Your name here?
49 |
50 |
51 | ## License
52 |
53 | This code is released under the _3-clause BSD License_ (aka _new BSD License_ or _modified BSD License_).
54 | The full text is included in the LICENSE file in the root of the repository.
55 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 9405A431162479BA00E83BB5 /* SVPullToRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 9405A430162479BA00E83BB5 /* SVPullToRefresh.m */; };
11 | 9405A43516247A0600E83BB5 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9405A43416247A0600E83BB5 /* QuartzCore.framework */; };
12 | 9438A10D1593E4110042CA60 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9438A10B1593E4110042CA60 /* InfoPlist.strings */; };
13 | 9438A1171593E4120042CA60 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9438A1161593E4120042CA60 /* SenTestingKit.framework */; };
14 | 9438A1191593E4120042CA60 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9438A1181593E4120042CA60 /* UIKit.framework */; };
15 | 9438A11B1593E4120042CA60 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9438A11A1593E4120042CA60 /* Foundation.framework */; };
16 | 9438A11E1593E4120042CA60 /* UITableView+NXEmptyView.framework in Resources */ = {isa = PBXBuildFile; fileRef = 9438A1061593E4110042CA60 /* UITableView+NXEmptyView.framework */; };
17 | 9438A1241593E4120042CA60 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9438A1221593E4120042CA60 /* InfoPlist.strings */; };
18 | 9438A1271593E4120042CA60 /* UITableView_NXEmptyViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9438A1261593E4120042CA60 /* UITableView_NXEmptyViewTests.m */; };
19 | 9438A1361593E4410042CA60 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9438A1181593E4120042CA60 /* UIKit.framework */; };
20 | 9438A1371593E4410042CA60 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9438A11A1593E4120042CA60 /* Foundation.framework */; };
21 | 9438A1391593E4410042CA60 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9438A1381593E4410042CA60 /* CoreGraphics.framework */; };
22 | 9438A13F1593E4410042CA60 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9438A13D1593E4410042CA60 /* InfoPlist.strings */; };
23 | 9438A1411593E4410042CA60 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9438A1401593E4410042CA60 /* main.m */; };
24 | 9438A1451593E4410042CA60 /* NXAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9438A1441593E4410042CA60 /* NXAppDelegate.m */; };
25 | 9438A1481593E4410042CA60 /* NXViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9438A1471593E4410042CA60 /* NXViewController.m */; };
26 | 9438A14B1593E4410042CA60 /* NXViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9438A1491593E4410042CA60 /* NXViewController.xib */; };
27 | 9438A1511593E45E0042CA60 /* UITableView+NXEmptyView.h in Headers */ = {isa = PBXBuildFile; fileRef = 9438A14F1593E45E0042CA60 /* UITableView+NXEmptyView.h */; settings = {ATTRIBUTES = (Public, ); }; };
28 | 9438A1521593E45E0042CA60 /* UITableView+NXEmptyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9438A1501593E45E0042CA60 /* UITableView+NXEmptyView.m */; };
29 | 9438A1531593E4780042CA60 /* UITableView+NXEmptyView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9438A1061593E4110042CA60 /* UITableView+NXEmptyView.framework */; };
30 | 9438A18415940E490042CA60 /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9438A17C15940E380042CA60 /* libOCMock.a */; };
31 | 9438A1861594196E0042CA60 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9438A1381593E4410042CA60 /* CoreGraphics.framework */; };
32 | /* End PBXBuildFile section */
33 |
34 | /* Begin PBXContainerItemProxy section */
35 | 9438A11C1593E4120042CA60 /* PBXContainerItemProxy */ = {
36 | isa = PBXContainerItemProxy;
37 | containerPortal = 9438A0F91593E4110042CA60 /* Project object */;
38 | proxyType = 1;
39 | remoteGlobalIDString = 9438A1051593E4110042CA60;
40 | remoteInfo = "UITableView+NXEmptyView";
41 | };
42 | 9438A1541593E6FD0042CA60 /* PBXContainerItemProxy */ = {
43 | isa = PBXContainerItemProxy;
44 | containerPortal = 9438A0F91593E4110042CA60 /* Project object */;
45 | proxyType = 1;
46 | remoteGlobalIDString = 9438A1051593E4110042CA60;
47 | remoteInfo = "UITableView+NXEmptyView";
48 | };
49 | /* End PBXContainerItemProxy section */
50 |
51 | /* Begin PBXFileReference section */
52 | 9405A42F162479BA00E83BB5 /* SVPullToRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SVPullToRefresh.h; path = Libraries/SVPullToRefresh/SVPullToRefresh.h; sourceTree = SOURCE_ROOT; };
53 | 9405A430162479BA00E83BB5 /* SVPullToRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SVPullToRefresh.m; path = Libraries/SVPullToRefresh/SVPullToRefresh.m; sourceTree = SOURCE_ROOT; };
54 | 9405A43416247A0600E83BB5 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
55 | 9438A1061593E4110042CA60 /* UITableView+NXEmptyView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "UITableView+NXEmptyView.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
56 | 9438A10A1593E4110042CA60 /* UITableView+NXEmptyView-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "UITableView+NXEmptyView-Info.plist"; sourceTree = ""; };
57 | 9438A10C1593E4110042CA60 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
58 | 9438A10E1593E4110042CA60 /* UITableView+NXEmptyView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UITableView+NXEmptyView-Prefix.pch"; sourceTree = ""; };
59 | 9438A1141593E4120042CA60 /* UITableView+NXEmptyViewTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "UITableView+NXEmptyViewTests.octest"; sourceTree = BUILT_PRODUCTS_DIR; };
60 | 9438A1161593E4120042CA60 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
61 | 9438A1181593E4120042CA60 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
62 | 9438A11A1593E4120042CA60 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
63 | 9438A1211593E4120042CA60 /* UITableView+NXEmptyViewTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "UITableView+NXEmptyViewTests-Info.plist"; sourceTree = ""; };
64 | 9438A1231593E4120042CA60 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
65 | 9438A1251593E4120042CA60 /* UITableView_NXEmptyViewTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UITableView_NXEmptyViewTests.h; sourceTree = ""; };
66 | 9438A1261593E4120042CA60 /* UITableView_NXEmptyViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UITableView_NXEmptyViewTests.m; sourceTree = ""; };
67 | 9438A1341593E4410042CA60 /* DemoApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
68 | 9438A1381593E4410042CA60 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
69 | 9438A13C1593E4410042CA60 /* DemoApp-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DemoApp-Info.plist"; sourceTree = ""; };
70 | 9438A13E1593E4410042CA60 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
71 | 9438A1401593E4410042CA60 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
72 | 9438A1421593E4410042CA60 /* DemoApp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DemoApp-Prefix.pch"; sourceTree = ""; };
73 | 9438A1431593E4410042CA60 /* NXAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NXAppDelegate.h; sourceTree = ""; };
74 | 9438A1441593E4410042CA60 /* NXAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NXAppDelegate.m; sourceTree = ""; };
75 | 9438A1461593E4410042CA60 /* NXViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NXViewController.h; sourceTree = ""; };
76 | 9438A1471593E4410042CA60 /* NXViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NXViewController.m; sourceTree = ""; };
77 | 9438A14A1593E4410042CA60 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/NXViewController.xib; sourceTree = ""; };
78 | 9438A14F1593E45E0042CA60 /* UITableView+NXEmptyView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableView+NXEmptyView.h"; sourceTree = ""; };
79 | 9438A1501593E45E0042CA60 /* UITableView+NXEmptyView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableView+NXEmptyView.m"; sourceTree = ""; };
80 | 9438A17C15940E380042CA60 /* libOCMock.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libOCMock.a; sourceTree = ""; };
81 | 9438A17E15940E380042CA60 /* NSNotificationCenter+OCMAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+OCMAdditions.h"; sourceTree = ""; };
82 | 9438A17F15940E380042CA60 /* OCMArg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OCMArg.h; sourceTree = ""; };
83 | 9438A18015940E380042CA60 /* OCMConstraint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OCMConstraint.h; sourceTree = ""; };
84 | 9438A18115940E380042CA60 /* OCMock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OCMock.h; sourceTree = ""; };
85 | 9438A18215940E380042CA60 /* OCMockObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OCMockObject.h; sourceTree = ""; };
86 | 9438A18315940E380042CA60 /* OCMockRecorder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OCMockRecorder.h; sourceTree = ""; };
87 | /* End PBXFileReference section */
88 |
89 | /* Begin PBXFrameworksBuildPhase section */
90 | 9438A1001593E4110042CA60 /* Frameworks */ = {
91 | isa = PBXFrameworksBuildPhase;
92 | buildActionMask = 2147483647;
93 | files = (
94 | );
95 | runOnlyForDeploymentPostprocessing = 0;
96 | };
97 | 9438A1101593E4120042CA60 /* Frameworks */ = {
98 | isa = PBXFrameworksBuildPhase;
99 | buildActionMask = 2147483647;
100 | files = (
101 | 9438A1861594196E0042CA60 /* CoreGraphics.framework in Frameworks */,
102 | 9438A1171593E4120042CA60 /* SenTestingKit.framework in Frameworks */,
103 | 9438A18415940E490042CA60 /* libOCMock.a in Frameworks */,
104 | 9438A1191593E4120042CA60 /* UIKit.framework in Frameworks */,
105 | 9438A11B1593E4120042CA60 /* Foundation.framework in Frameworks */,
106 | );
107 | runOnlyForDeploymentPostprocessing = 0;
108 | };
109 | 9438A1311593E4410042CA60 /* Frameworks */ = {
110 | isa = PBXFrameworksBuildPhase;
111 | buildActionMask = 2147483647;
112 | files = (
113 | 9438A1531593E4780042CA60 /* UITableView+NXEmptyView.framework in Frameworks */,
114 | 9438A1361593E4410042CA60 /* UIKit.framework in Frameworks */,
115 | 9438A1371593E4410042CA60 /* Foundation.framework in Frameworks */,
116 | 9438A1391593E4410042CA60 /* CoreGraphics.framework in Frameworks */,
117 | 9405A43516247A0600E83BB5 /* QuartzCore.framework in Frameworks */,
118 | );
119 | runOnlyForDeploymentPostprocessing = 0;
120 | };
121 | /* End PBXFrameworksBuildPhase section */
122 |
123 | /* Begin PBXGroup section */
124 | 9405A433162479BF00E83BB5 /* SVPullToRefresh */ = {
125 | isa = PBXGroup;
126 | children = (
127 | 9405A42F162479BA00E83BB5 /* SVPullToRefresh.h */,
128 | 9405A430162479BA00E83BB5 /* SVPullToRefresh.m */,
129 | );
130 | name = SVPullToRefresh;
131 | sourceTree = "";
132 | };
133 | 9405A43616247A1700E83BB5 /* Frameworks */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 9405A43416247A0600E83BB5 /* QuartzCore.framework */,
137 | );
138 | name = Frameworks;
139 | sourceTree = "";
140 | };
141 | 9438A0F71593E4110042CA60 = {
142 | isa = PBXGroup;
143 | children = (
144 | 9438A17915940E010042CA60 /* Libraries */,
145 | 9438A1081593E4110042CA60 /* UITableView+NXEmptyView */,
146 | 9438A11F1593E4120042CA60 /* UITableView+NXEmptyViewTests */,
147 | 9438A13A1593E4410042CA60 /* DemoApp */,
148 | 9438A1151593E4120042CA60 /* Frameworks */,
149 | 9438A1071593E4110042CA60 /* Products */,
150 | );
151 | sourceTree = "";
152 | };
153 | 9438A1071593E4110042CA60 /* Products */ = {
154 | isa = PBXGroup;
155 | children = (
156 | 9438A1061593E4110042CA60 /* UITableView+NXEmptyView.framework */,
157 | 9438A1141593E4120042CA60 /* UITableView+NXEmptyViewTests.octest */,
158 | 9438A1341593E4410042CA60 /* DemoApp.app */,
159 | );
160 | name = Products;
161 | sourceTree = "";
162 | };
163 | 9438A1081593E4110042CA60 /* UITableView+NXEmptyView */ = {
164 | isa = PBXGroup;
165 | children = (
166 | 9438A14F1593E45E0042CA60 /* UITableView+NXEmptyView.h */,
167 | 9438A1501593E45E0042CA60 /* UITableView+NXEmptyView.m */,
168 | 9438A1091593E4110042CA60 /* Supporting Files */,
169 | );
170 | path = "UITableView+NXEmptyView";
171 | sourceTree = "";
172 | };
173 | 9438A1091593E4110042CA60 /* Supporting Files */ = {
174 | isa = PBXGroup;
175 | children = (
176 | 9438A10A1593E4110042CA60 /* UITableView+NXEmptyView-Info.plist */,
177 | 9438A10B1593E4110042CA60 /* InfoPlist.strings */,
178 | 9438A10E1593E4110042CA60 /* UITableView+NXEmptyView-Prefix.pch */,
179 | );
180 | name = "Supporting Files";
181 | sourceTree = "";
182 | };
183 | 9438A1151593E4120042CA60 /* Frameworks */ = {
184 | isa = PBXGroup;
185 | children = (
186 | 9438A1161593E4120042CA60 /* SenTestingKit.framework */,
187 | 9438A1181593E4120042CA60 /* UIKit.framework */,
188 | 9438A11A1593E4120042CA60 /* Foundation.framework */,
189 | 9438A1381593E4410042CA60 /* CoreGraphics.framework */,
190 | );
191 | name = Frameworks;
192 | sourceTree = "";
193 | };
194 | 9438A11F1593E4120042CA60 /* UITableView+NXEmptyViewTests */ = {
195 | isa = PBXGroup;
196 | children = (
197 | 9438A1251593E4120042CA60 /* UITableView_NXEmptyViewTests.h */,
198 | 9438A1261593E4120042CA60 /* UITableView_NXEmptyViewTests.m */,
199 | 9438A1201593E4120042CA60 /* Supporting Files */,
200 | );
201 | path = "UITableView+NXEmptyViewTests";
202 | sourceTree = "";
203 | };
204 | 9438A1201593E4120042CA60 /* Supporting Files */ = {
205 | isa = PBXGroup;
206 | children = (
207 | 9438A1211593E4120042CA60 /* UITableView+NXEmptyViewTests-Info.plist */,
208 | 9438A1221593E4120042CA60 /* InfoPlist.strings */,
209 | );
210 | name = "Supporting Files";
211 | sourceTree = "";
212 | };
213 | 9438A13A1593E4410042CA60 /* DemoApp */ = {
214 | isa = PBXGroup;
215 | children = (
216 | 9438A1431593E4410042CA60 /* NXAppDelegate.h */,
217 | 9438A1441593E4410042CA60 /* NXAppDelegate.m */,
218 | 9438A1461593E4410042CA60 /* NXViewController.h */,
219 | 9438A1471593E4410042CA60 /* NXViewController.m */,
220 | 9438A1491593E4410042CA60 /* NXViewController.xib */,
221 | 9405A433162479BF00E83BB5 /* SVPullToRefresh */,
222 | 9438A13B1593E4410042CA60 /* Supporting Files */,
223 | 9405A43616247A1700E83BB5 /* Frameworks */,
224 | );
225 | path = DemoApp;
226 | sourceTree = "";
227 | };
228 | 9438A13B1593E4410042CA60 /* Supporting Files */ = {
229 | isa = PBXGroup;
230 | children = (
231 | 9438A13C1593E4410042CA60 /* DemoApp-Info.plist */,
232 | 9438A13D1593E4410042CA60 /* InfoPlist.strings */,
233 | 9438A1401593E4410042CA60 /* main.m */,
234 | 9438A1421593E4410042CA60 /* DemoApp-Prefix.pch */,
235 | );
236 | name = "Supporting Files";
237 | sourceTree = "";
238 | };
239 | 9438A17915940E010042CA60 /* Libraries */ = {
240 | isa = PBXGroup;
241 | children = (
242 | 9438A17C15940E380042CA60 /* libOCMock.a */,
243 | 9438A17D15940E380042CA60 /* OCMock */,
244 | );
245 | path = Libraries;
246 | sourceTree = "";
247 | };
248 | 9438A17D15940E380042CA60 /* OCMock */ = {
249 | isa = PBXGroup;
250 | children = (
251 | 9438A17E15940E380042CA60 /* NSNotificationCenter+OCMAdditions.h */,
252 | 9438A17F15940E380042CA60 /* OCMArg.h */,
253 | 9438A18015940E380042CA60 /* OCMConstraint.h */,
254 | 9438A18115940E380042CA60 /* OCMock.h */,
255 | 9438A18215940E380042CA60 /* OCMockObject.h */,
256 | 9438A18315940E380042CA60 /* OCMockRecorder.h */,
257 | );
258 | path = OCMock;
259 | sourceTree = "";
260 | };
261 | /* End PBXGroup section */
262 |
263 | /* Begin PBXHeadersBuildPhase section */
264 | 9438A1011593E4110042CA60 /* Headers */ = {
265 | isa = PBXHeadersBuildPhase;
266 | buildActionMask = 2147483647;
267 | files = (
268 | 9438A1511593E45E0042CA60 /* UITableView+NXEmptyView.h in Headers */,
269 | );
270 | runOnlyForDeploymentPostprocessing = 0;
271 | };
272 | /* End PBXHeadersBuildPhase section */
273 |
274 | /* Begin PBXNativeTarget section */
275 | 9438A1051593E4110042CA60 /* UITableView+NXEmptyView */ = {
276 | isa = PBXNativeTarget;
277 | buildConfigurationList = 9438A12A1593E4120042CA60 /* Build configuration list for PBXNativeTarget "UITableView+NXEmptyView" */;
278 | buildPhases = (
279 | 9438A0FE1593E4110042CA60 /* ShellScript */,
280 | 9438A0FF1593E4110042CA60 /* Sources */,
281 | 9438A1001593E4110042CA60 /* Frameworks */,
282 | 9438A1011593E4110042CA60 /* Headers */,
283 | 9438A1021593E4110042CA60 /* Resources */,
284 | 9438A1031593E4110042CA60 /* ShellScript */,
285 | 9438A1041593E4110042CA60 /* ShellScript */,
286 | );
287 | buildRules = (
288 | );
289 | dependencies = (
290 | );
291 | name = "UITableView+NXEmptyView";
292 | productName = "UITableView+NXEmptyView";
293 | productReference = 9438A1061593E4110042CA60 /* UITableView+NXEmptyView.framework */;
294 | productType = "com.apple.product-type.bundle";
295 | };
296 | 9438A1131593E4120042CA60 /* UITableView+NXEmptyViewTests */ = {
297 | isa = PBXNativeTarget;
298 | buildConfigurationList = 9438A12D1593E4120042CA60 /* Build configuration list for PBXNativeTarget "UITableView+NXEmptyViewTests" */;
299 | buildPhases = (
300 | 9438A10F1593E4120042CA60 /* Sources */,
301 | 9438A1101593E4120042CA60 /* Frameworks */,
302 | 9438A1111593E4120042CA60 /* Resources */,
303 | 9438A1121593E4120042CA60 /* ShellScript */,
304 | );
305 | buildRules = (
306 | );
307 | dependencies = (
308 | 9438A11D1593E4120042CA60 /* PBXTargetDependency */,
309 | );
310 | name = "UITableView+NXEmptyViewTests";
311 | productName = "UITableView+NXEmptyViewTests";
312 | productReference = 9438A1141593E4120042CA60 /* UITableView+NXEmptyViewTests.octest */;
313 | productType = "com.apple.product-type.bundle";
314 | };
315 | 9438A1331593E4410042CA60 /* DemoApp */ = {
316 | isa = PBXNativeTarget;
317 | buildConfigurationList = 9438A14C1593E4410042CA60 /* Build configuration list for PBXNativeTarget "DemoApp" */;
318 | buildPhases = (
319 | 9438A1301593E4410042CA60 /* Sources */,
320 | 9438A1311593E4410042CA60 /* Frameworks */,
321 | 9438A1321593E4410042CA60 /* Resources */,
322 | );
323 | buildRules = (
324 | );
325 | dependencies = (
326 | 9438A1551593E6FD0042CA60 /* PBXTargetDependency */,
327 | );
328 | name = DemoApp;
329 | productName = DemoApp;
330 | productReference = 9438A1341593E4410042CA60 /* DemoApp.app */;
331 | productType = "com.apple.product-type.application";
332 | };
333 | /* End PBXNativeTarget section */
334 |
335 | /* Begin PBXProject section */
336 | 9438A0F91593E4110042CA60 /* Project object */ = {
337 | isa = PBXProject;
338 | attributes = {
339 | LastUpgradeCheck = 0440;
340 | ORGANIZATIONNAME = nxtbgthng.com;
341 | };
342 | buildConfigurationList = 9438A0FC1593E4110042CA60 /* Build configuration list for PBXProject "UITableView+NXEmptyView" */;
343 | compatibilityVersion = "Xcode 3.2";
344 | developmentRegion = English;
345 | hasScannedForEncodings = 0;
346 | knownRegions = (
347 | en,
348 | );
349 | mainGroup = 9438A0F71593E4110042CA60;
350 | productRefGroup = 9438A1071593E4110042CA60 /* Products */;
351 | projectDirPath = "";
352 | projectRoot = "";
353 | targets = (
354 | 9438A1051593E4110042CA60 /* UITableView+NXEmptyView */,
355 | 9438A1131593E4120042CA60 /* UITableView+NXEmptyViewTests */,
356 | 9438A1331593E4410042CA60 /* DemoApp */,
357 | );
358 | };
359 | /* End PBXProject section */
360 |
361 | /* Begin PBXResourcesBuildPhase section */
362 | 9438A1021593E4110042CA60 /* Resources */ = {
363 | isa = PBXResourcesBuildPhase;
364 | buildActionMask = 2147483647;
365 | files = (
366 | 9438A10D1593E4110042CA60 /* InfoPlist.strings in Resources */,
367 | );
368 | runOnlyForDeploymentPostprocessing = 0;
369 | };
370 | 9438A1111593E4120042CA60 /* Resources */ = {
371 | isa = PBXResourcesBuildPhase;
372 | buildActionMask = 2147483647;
373 | files = (
374 | 9438A11E1593E4120042CA60 /* UITableView+NXEmptyView.framework in Resources */,
375 | 9438A1241593E4120042CA60 /* InfoPlist.strings in Resources */,
376 | );
377 | runOnlyForDeploymentPostprocessing = 0;
378 | };
379 | 9438A1321593E4410042CA60 /* Resources */ = {
380 | isa = PBXResourcesBuildPhase;
381 | buildActionMask = 2147483647;
382 | files = (
383 | 9438A13F1593E4410042CA60 /* InfoPlist.strings in Resources */,
384 | 9438A14B1593E4410042CA60 /* NXViewController.xib in Resources */,
385 | );
386 | runOnlyForDeploymentPostprocessing = 0;
387 | };
388 | /* End PBXResourcesBuildPhase section */
389 |
390 | /* Begin PBXShellScriptBuildPhase section */
391 | 9438A0FE1593E4110042CA60 /* ShellScript */ = {
392 | isa = PBXShellScriptBuildPhase;
393 | buildActionMask = 2147483647;
394 | files = (
395 | );
396 | inputPaths = (
397 | );
398 | outputPaths = (
399 | );
400 | runOnlyForDeploymentPostprocessing = 0;
401 | shellPath = /bin/sh;
402 | shellScript = "set -e\n\nset +u\nif [[ $UFW_MASTER_SCRIPT_RUNNING ]]\nthen\n # Nothing for the slave script to do\n exit 0\nfi\nset -u\n\nif [[ \"$SDK_NAME\" =~ ([A-Za-z]+) ]]\nthen\n UFW_SDK_PLATFORM=${BASH_REMATCH[1]}\nelse\n echo \"Could not find platform name from SDK_NAME: $SDK_NAME\"\n exit 1\nfi\n\nif [[ \"$SDK_NAME\" =~ ([0-9]+.*$) ]]\nthen\n\tUFW_SDK_VERSION=${BASH_REMATCH[1]}\nelse\n echo \"Could not find sdk version from SDK_NAME: $SDK_NAME\"\n exit 1\nfi\n\nif [[ \"$UFW_SDK_PLATFORM\" = \"iphoneos\" ]]\nthen\n UFW_OTHER_PLATFORM=iphonesimulator\nelse\n UFW_OTHER_PLATFORM=iphoneos\nfi\n\nif [[ \"$BUILT_PRODUCTS_DIR\" =~ (.*)$UFW_SDK_PLATFORM$ ]]\nthen\n UFW_OTHER_BUILT_PRODUCTS_DIR=\"${BASH_REMATCH[1]}${UFW_OTHER_PLATFORM}\"\nelse\n echo \"Could not find $UFW_SDK_PLATFORM in $BUILT_PRODUCTS_DIR\"\n exit 1\nfi\n\n\n# Short-circuit if all binaries are up to date\n\nif [[ -f \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" ]] && \\\n [[ -f \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/${EXECUTABLE_PATH}\" ]] && \\\n [[ ! \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" -nt \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/${EXECUTABLE_PATH}\" ]]\n [[ -f \"${UFW_OTHER_BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" ]] && \\\n [[ -f \"${UFW_OTHER_BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/${EXECUTABLE_PATH}\" ]] && \\\n [[ ! \"${UFW_OTHER_BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" -nt \"${UFW_OTHER_BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/${EXECUTABLE_PATH}\" ]]\nthen\n exit 0\nfi\n\n\n# Clean other platform if needed\n\nif [[ ! -f \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" ]]\nthen\n\techo \"Platform \\\"$UFW_SDK_PLATFORM\\\" was cleaned recently. Cleaning \\\"$UFW_OTHER_PLATFORM\\\" as well\"\n\techo xcodebuild -project \"${PROJECT_FILE_PATH}\" -target \"${TARGET_NAME}\" -configuration \"${CONFIGURATION}\" -sdk ${UFW_OTHER_PLATFORM}${UFW_SDK_VERSION} BUILD_DIR=\"${BUILD_DIR}\" CONFIGURATION_TEMP_DIR=\"${PROJECT_TEMP_DIR}/${CONFIGURATION}-${UFW_OTHER_PLATFORM}\" clean\n\txcodebuild -project \"${PROJECT_FILE_PATH}\" -target \"${TARGET_NAME}\" -configuration \"${CONFIGURATION}\" -sdk ${UFW_OTHER_PLATFORM}${UFW_SDK_VERSION} BUILD_DIR=\"${BUILD_DIR}\" CONFIGURATION_TEMP_DIR=\"${PROJECT_TEMP_DIR}/${CONFIGURATION}-${UFW_OTHER_PLATFORM}\" clean\nfi\n\n\n# Make sure we are building from fresh binaries\n\nrm -rf \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\"\nrm -rf \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework\"\nrm -rf \"${UFW_OTHER_BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\"\nrm -rf \"${UFW_OTHER_BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework\"\n";
403 | };
404 | 9438A1031593E4110042CA60 /* ShellScript */ = {
405 | isa = PBXShellScriptBuildPhase;
406 | buildActionMask = 2147483647;
407 | files = (
408 | );
409 | inputPaths = (
410 | );
411 | outputPaths = (
412 | );
413 | runOnlyForDeploymentPostprocessing = 0;
414 | shellPath = /bin/sh;
415 | shellScript = "HEADERS_ROOT=$SRCROOT/$PRODUCT_NAME\nFRAMEWORK_HEADERS_DIR=\"$BUILT_PRODUCTS_DIR/$WRAPPER_NAME/Versions/$FRAMEWORK_VERSION/Headers\"\n\n## only header files expected at this point\nPUBLIC_HEADERS=$(find $FRAMEWORK_HEADERS_DIR/. -not -type d 2> /dev/null | sed -e \"s@.*/@@g\")\n\nFIND_OPTS=\"\"\nfor PUBLIC_HEADER in $PUBLIC_HEADERS; do\n if [ -n \"$FIND_OPTS\" ]; then\n FIND_OPTS=\"$FIND_OPTS -o\"\n fi\n FIND_OPTS=\"$FIND_OPTS -name '$PUBLIC_HEADER'\"\ndone\n\nif [ -n \"$FIND_OPTS\" ]; then\n for ORIG_HEADER in $(eval \"find $HEADERS_ROOT/. $FIND_OPTS\" 2> /dev/null | sed -e \"s@^$HEADERS_ROOT/./@@g\"); do\n PUBLIC_HEADER=$(basename $ORIG_HEADER)\n RELATIVE_PATH=$(dirname $ORIG_HEADER)\n if [ -e $FRAMEWORK_HEADERS_DIR/$PUBLIC_HEADER ]; then\n mkdir -p \"$FRAMEWORK_HEADERS_DIR/$RELATIVE_PATH\"\n mv \"$FRAMEWORK_HEADERS_DIR/$PUBLIC_HEADER\" \"$FRAMEWORK_HEADERS_DIR/$RELATIVE_PATH/$PUBLIC_HEADER\"\n fi\n done\nfi\n";
416 | };
417 | 9438A1041593E4110042CA60 /* ShellScript */ = {
418 | isa = PBXShellScriptBuildPhase;
419 | buildActionMask = 2147483647;
420 | files = (
421 | );
422 | inputPaths = (
423 | );
424 | outputPaths = (
425 | );
426 | runOnlyForDeploymentPostprocessing = 0;
427 | shellPath = /bin/sh;
428 | shellScript = "set -e\n\nset +u\nif [[ $UFW_MASTER_SCRIPT_RUNNING ]]\nthen\n # Nothing for the slave script to do\n exit 0\nfi\nset -u\nexport UFW_MASTER_SCRIPT_RUNNING=1\n\n\n# Functions\n\n## List files in the specified directory, storing to the specified array.\n#\n# @param $1 The path to list\n# @param $2 The name of the array to fill\n#\n##\nlist_files ()\n{\n filelist=$(ls \"$1\")\n while read line\n do\n eval \"$2[\\${#$2[*]}]=\\\"\\$line\\\"\"\n done <<< \"$filelist\"\n}\n\n\n# Sanity check\n\nif [[ ! -f \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" ]]\nthen\n echo \"Framework target \\\"${TARGET_NAME}\\\" had no source files to build from. Make sure your source files have the correct target membership\"\n exit 1\nfi\n\n\n# Gather information\n\nif [[ \"$SDK_NAME\" =~ ([A-Za-z]+) ]]\nthen\n UFW_SDK_PLATFORM=${BASH_REMATCH[1]}\nelse\n echo \"Could not find platform name from SDK_NAME: $SDK_NAME\"\n exit 1\nfi\n\nif [[ \"$SDK_NAME\" =~ ([0-9]+.*$) ]]\nthen\n UFW_SDK_VERSION=${BASH_REMATCH[1]}\nelse\n echo \"Could not find sdk version from SDK_NAME: $SDK_NAME\"\n exit 1\nfi\n\nif [[ \"$UFW_SDK_PLATFORM\" = \"iphoneos\" ]]\nthen\n UFW_OTHER_PLATFORM=iphonesimulator\nelse\n UFW_OTHER_PLATFORM=iphoneos\nfi\n\nif [[ \"$BUILT_PRODUCTS_DIR\" =~ (.*)$UFW_SDK_PLATFORM$ ]]\nthen\n UFW_OTHER_BUILT_PRODUCTS_DIR=\"${BASH_REMATCH[1]}${UFW_OTHER_PLATFORM}\"\nelse\n echo \"Could not find $UFW_SDK_PLATFORM in $BUILT_PRODUCTS_DIR\"\n exit 1\nfi\n\n\n# Short-circuit if all binaries are up to date.\n# We already checked the other platform in the prerun script.\n\nif [[ -f \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" ]] && [[ -f \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/${EXECUTABLE_PATH}\" ]] && [[ ! \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" -nt \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/${EXECUTABLE_PATH}\" ]]\nthen\n exit 0\nfi\n\n\n# Make sure the other platform gets built\n\necho \"Build other platform\"\n\necho xcodebuild -project \"${PROJECT_FILE_PATH}\" -target \"${TARGET_NAME}\" -configuration \"${CONFIGURATION}\" -sdk ${UFW_OTHER_PLATFORM}${UFW_SDK_VERSION} BUILD_DIR=\"${BUILD_DIR}\" CONFIGURATION_TEMP_DIR=\"${PROJECT_TEMP_DIR}/${CONFIGURATION}-${UFW_OTHER_PLATFORM}\" $ACTION\nxcodebuild -project \"${PROJECT_FILE_PATH}\" -target \"${TARGET_NAME}\" -configuration \"${CONFIGURATION}\" -sdk ${UFW_OTHER_PLATFORM}${UFW_SDK_VERSION} BUILD_DIR=\"${BUILD_DIR}\" CONFIGURATION_TEMP_DIR=\"${PROJECT_TEMP_DIR}/${CONFIGURATION}-${UFW_OTHER_PLATFORM}\" $ACTION\n\n\n# Build the fat static library binary\n\necho \"Create universal static library\"\n\necho \"$PLATFORM_DEVELOPER_BIN_DIR/libtool\" -static \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" \"${UFW_OTHER_BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" -o \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}.temp\"\n\"$PLATFORM_DEVELOPER_BIN_DIR/libtool\" -static \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" \"${UFW_OTHER_BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\" -o \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}.temp\"\n\necho mv \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}.temp\" \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\"\nmv \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}.temp\" \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\"\n\n\n# Build framework structure\n\necho \"Build symlinks\"\n\necho ln -sfh A \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Versions/Current\"\nln -sfh A \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Versions/Current\"\necho ln -sfh Versions/Current/Headers \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Headers\"\nln -sfh Versions/Current/Headers \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Headers\"\necho ln -sfh Versions/Current/Resources \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Resources\"\nln -sfh Versions/Current/Resources \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Resources\"\necho ln -sfh \"Versions/Current/${EXECUTABLE_NAME}\" \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${EXECUTABLE_NAME}\"\nln -sfh \"Versions/Current/${EXECUTABLE_NAME}\" \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${EXECUTABLE_NAME}\"\n\n\n# Link to binary for unit tests\n\nmkdir -p \"${BUILT_PRODUCTS_DIR}/.fake_fw_testing.framework\"\nln -sfh \"../${WRAPPER_NAME}/${EXECUTABLE_NAME}\" \"${BUILT_PRODUCTS_DIR}/.fake_fw_testing.framework/.fake_fw_testing\"\n\n\n# Build embedded framework structure\n\necho \"Build Embedded Framework\"\n\necho rm -rf \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework\"\nrm -rf \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework\"\necho mkdir -p \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/Resources\"\nmkdir -p \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/Resources\"\necho cp -a \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}\" \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/\"\ncp -a \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}\" \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/\"\n\ndeclare -a UFW_FILE_LIST\nlist_files \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}\" UFW_FILE_LIST\nfor filename in \"${UFW_FILE_LIST[@]}\"\ndo\n if [[ \"${filename}\" != \"Info.plist\" ]] && [[ ! \"${filename}\" =~ .*\\.lproj$ ]]\n then\n echo ln -sfh \"../${WRAPPER_NAME}/Resources/${filename}\" \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/Resources/${filename}\"\n ln -sfh \"../${WRAPPER_NAME}/Resources/${filename}\" \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.embeddedframework/Resources/${filename}\"\n fi\ndone\n\n\n# Replace other platform's framework with a copy of this one (so that both have the same universal binary)\n\necho \"Copy from $UFW_SDK_PLATFORM to $UFW_OTHER_PLATFORM\"\n\necho rm -rf \"${BUILD_DIR}/${CONFIGURATION}-${UFW_OTHER_PLATFORM}\"\nrm -rf \"${BUILD_DIR}/${CONFIGURATION}-${UFW_OTHER_PLATFORM}\"\necho cp -a \"${BUILD_DIR}/${CONFIGURATION}-${UFW_SDK_PLATFORM}\" \"${BUILD_DIR}/${CONFIGURATION}-${UFW_OTHER_PLATFORM}\"\ncp -a \"${BUILD_DIR}/${CONFIGURATION}-${UFW_SDK_PLATFORM}\" \"${BUILD_DIR}/${CONFIGURATION}-${UFW_OTHER_PLATFORM}\"\n";
429 | };
430 | 9438A1121593E4120042CA60 /* ShellScript */ = {
431 | isa = PBXShellScriptBuildPhase;
432 | buildActionMask = 2147483647;
433 | files = (
434 | );
435 | inputPaths = (
436 | );
437 | outputPaths = (
438 | );
439 | runOnlyForDeploymentPostprocessing = 0;
440 | shellPath = /bin/sh;
441 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
442 | };
443 | /* End PBXShellScriptBuildPhase section */
444 |
445 | /* Begin PBXSourcesBuildPhase section */
446 | 9438A0FF1593E4110042CA60 /* Sources */ = {
447 | isa = PBXSourcesBuildPhase;
448 | buildActionMask = 2147483647;
449 | files = (
450 | 9438A1521593E45E0042CA60 /* UITableView+NXEmptyView.m in Sources */,
451 | );
452 | runOnlyForDeploymentPostprocessing = 0;
453 | };
454 | 9438A10F1593E4120042CA60 /* Sources */ = {
455 | isa = PBXSourcesBuildPhase;
456 | buildActionMask = 2147483647;
457 | files = (
458 | 9438A1271593E4120042CA60 /* UITableView_NXEmptyViewTests.m in Sources */,
459 | );
460 | runOnlyForDeploymentPostprocessing = 0;
461 | };
462 | 9438A1301593E4410042CA60 /* Sources */ = {
463 | isa = PBXSourcesBuildPhase;
464 | buildActionMask = 2147483647;
465 | files = (
466 | 9438A1411593E4410042CA60 /* main.m in Sources */,
467 | 9438A1451593E4410042CA60 /* NXAppDelegate.m in Sources */,
468 | 9438A1481593E4410042CA60 /* NXViewController.m in Sources */,
469 | 9405A431162479BA00E83BB5 /* SVPullToRefresh.m in Sources */,
470 | );
471 | runOnlyForDeploymentPostprocessing = 0;
472 | };
473 | /* End PBXSourcesBuildPhase section */
474 |
475 | /* Begin PBXTargetDependency section */
476 | 9438A11D1593E4120042CA60 /* PBXTargetDependency */ = {
477 | isa = PBXTargetDependency;
478 | target = 9438A1051593E4110042CA60 /* UITableView+NXEmptyView */;
479 | targetProxy = 9438A11C1593E4120042CA60 /* PBXContainerItemProxy */;
480 | };
481 | 9438A1551593E6FD0042CA60 /* PBXTargetDependency */ = {
482 | isa = PBXTargetDependency;
483 | target = 9438A1051593E4110042CA60 /* UITableView+NXEmptyView */;
484 | targetProxy = 9438A1541593E6FD0042CA60 /* PBXContainerItemProxy */;
485 | };
486 | /* End PBXTargetDependency section */
487 |
488 | /* Begin PBXVariantGroup section */
489 | 9438A10B1593E4110042CA60 /* InfoPlist.strings */ = {
490 | isa = PBXVariantGroup;
491 | children = (
492 | 9438A10C1593E4110042CA60 /* en */,
493 | );
494 | name = InfoPlist.strings;
495 | sourceTree = "";
496 | };
497 | 9438A1221593E4120042CA60 /* InfoPlist.strings */ = {
498 | isa = PBXVariantGroup;
499 | children = (
500 | 9438A1231593E4120042CA60 /* en */,
501 | );
502 | name = InfoPlist.strings;
503 | sourceTree = "";
504 | };
505 | 9438A13D1593E4410042CA60 /* InfoPlist.strings */ = {
506 | isa = PBXVariantGroup;
507 | children = (
508 | 9438A13E1593E4410042CA60 /* en */,
509 | );
510 | name = InfoPlist.strings;
511 | sourceTree = "";
512 | };
513 | 9438A1491593E4410042CA60 /* NXViewController.xib */ = {
514 | isa = PBXVariantGroup;
515 | children = (
516 | 9438A14A1593E4410042CA60 /* en */,
517 | );
518 | name = NXViewController.xib;
519 | sourceTree = "";
520 | };
521 | /* End PBXVariantGroup section */
522 |
523 | /* Begin XCBuildConfiguration section */
524 | 9438A1281593E4120042CA60 /* Debug */ = {
525 | isa = XCBuildConfiguration;
526 | buildSettings = {
527 | ALWAYS_SEARCH_USER_PATHS = NO;
528 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
529 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
530 | CLANG_ENABLE_OBJC_ARC = YES;
531 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
532 | COPY_PHASE_STRIP = NO;
533 | GCC_C_LANGUAGE_STANDARD = gnu99;
534 | GCC_DYNAMIC_NO_PIC = NO;
535 | GCC_OPTIMIZATION_LEVEL = 0;
536 | GCC_PREPROCESSOR_DEFINITIONS = (
537 | "DEBUG=1",
538 | "$(inherited)",
539 | );
540 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
541 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
542 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
543 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
544 | GCC_WARN_UNUSED_VARIABLE = YES;
545 | IPHONEOS_DEPLOYMENT_TARGET = 4.3;
546 | SDKROOT = iphoneos;
547 | };
548 | name = Debug;
549 | };
550 | 9438A1291593E4120042CA60 /* Release */ = {
551 | isa = XCBuildConfiguration;
552 | buildSettings = {
553 | ALWAYS_SEARCH_USER_PATHS = NO;
554 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
555 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
556 | CLANG_ENABLE_OBJC_ARC = YES;
557 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
558 | COPY_PHASE_STRIP = YES;
559 | GCC_C_LANGUAGE_STANDARD = gnu99;
560 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
561 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
562 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
563 | GCC_WARN_UNUSED_VARIABLE = YES;
564 | IPHONEOS_DEPLOYMENT_TARGET = 4.3;
565 | SDKROOT = iphoneos;
566 | VALIDATE_PRODUCT = YES;
567 | };
568 | name = Release;
569 | };
570 | 9438A12B1593E4120042CA60 /* Debug */ = {
571 | isa = XCBuildConfiguration;
572 | buildSettings = {
573 | ARCHS = (
574 | armv6,
575 | "$(inherited)",
576 | );
577 | CONTENTS_FOLDER_PATH = "$(WRAPPER_NAME)/Versions/$(FRAMEWORK_VERSION)";
578 | DEAD_CODE_STRIPPING = NO;
579 | DYLIB_COMPATIBILITY_VERSION = 1;
580 | DYLIB_CURRENT_VERSION = 1;
581 | FRAMEWORK_VERSION = A;
582 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
583 | GCC_PREFIX_HEADER = "UITableView+NXEmptyView/UITableView+NXEmptyView-Prefix.pch";
584 | INFOPLIST_FILE = "UITableView+NXEmptyView/UITableView+NXEmptyView-Info.plist";
585 | INFOPLIST_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/Info.plist";
586 | INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
587 | LINK_WITH_STANDARD_LIBRARIES = NO;
588 | MACH_O_TYPE = mh_object;
589 | OTHER_LDFLAGS = "-ObjC";
590 | PRODUCT_NAME = "$(TARGET_NAME)";
591 | SKIP_INSTALL = YES;
592 | UNLOCALIZED_RESOURCES_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/Resources";
593 | WRAPPER_EXTENSION = framework;
594 | };
595 | name = Debug;
596 | };
597 | 9438A12C1593E4120042CA60 /* Release */ = {
598 | isa = XCBuildConfiguration;
599 | buildSettings = {
600 | ARCHS = (
601 | armv6,
602 | "$(inherited)",
603 | );
604 | CONTENTS_FOLDER_PATH = "$(WRAPPER_NAME)/Versions/$(FRAMEWORK_VERSION)";
605 | DEAD_CODE_STRIPPING = NO;
606 | DYLIB_COMPATIBILITY_VERSION = 1;
607 | DYLIB_CURRENT_VERSION = 1;
608 | FRAMEWORK_VERSION = A;
609 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
610 | GCC_PREFIX_HEADER = "UITableView+NXEmptyView/UITableView+NXEmptyView-Prefix.pch";
611 | INFOPLIST_FILE = "UITableView+NXEmptyView/UITableView+NXEmptyView-Info.plist";
612 | INFOPLIST_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/Info.plist";
613 | INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
614 | LINK_WITH_STANDARD_LIBRARIES = NO;
615 | MACH_O_TYPE = mh_object;
616 | OTHER_LDFLAGS = "-ObjC";
617 | PRODUCT_NAME = "$(TARGET_NAME)";
618 | SKIP_INSTALL = YES;
619 | UNLOCALIZED_RESOURCES_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/Resources";
620 | WRAPPER_EXTENSION = framework;
621 | };
622 | name = Release;
623 | };
624 | 9438A12E1593E4120042CA60 /* Debug */ = {
625 | isa = XCBuildConfiguration;
626 | buildSettings = {
627 | FRAMEWORK_SEARCH_PATHS = (
628 | "\"$(SDKROOT)/Developer/Library/Frameworks\"",
629 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
630 | );
631 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
632 | GCC_PREFIX_HEADER = "UITableView+NXEmptyView/UITableView+NXEmptyView-Prefix.pch";
633 | HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/Libraries";
634 | INFOPLIST_FILE = "UITableView+NXEmptyViewTests/UITableView+NXEmptyViewTests-Info.plist";
635 | LIBRARY_SEARCH_PATHS = (
636 | "$(inherited)",
637 | "\"$(SRCROOT)/Libraries\"",
638 | );
639 | OTHER_LDFLAGS = (
640 | "-framework",
641 | SenTestingKit,
642 | "-framework",
643 | .fake_fw_testing,
644 | "-ObjC",
645 | "-force_load",
646 | "${PROJECT_DIR}/Libraries/libOCMock.a",
647 | );
648 | PRODUCT_NAME = "$(TARGET_NAME)";
649 | WRAPPER_EXTENSION = octest;
650 | };
651 | name = Debug;
652 | };
653 | 9438A12F1593E4120042CA60 /* Release */ = {
654 | isa = XCBuildConfiguration;
655 | buildSettings = {
656 | FRAMEWORK_SEARCH_PATHS = (
657 | "\"$(SDKROOT)/Developer/Library/Frameworks\"",
658 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
659 | );
660 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
661 | GCC_PREFIX_HEADER = "UITableView+NXEmptyView/UITableView+NXEmptyView-Prefix.pch";
662 | HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/Libraries";
663 | INFOPLIST_FILE = "UITableView+NXEmptyViewTests/UITableView+NXEmptyViewTests-Info.plist";
664 | LIBRARY_SEARCH_PATHS = (
665 | "$(inherited)",
666 | "\"$(SRCROOT)/Libraries\"",
667 | );
668 | OTHER_LDFLAGS = (
669 | "-framework",
670 | SenTestingKit,
671 | "-framework",
672 | .fake_fw_testing,
673 | "-ObjC",
674 | "-force_load",
675 | "${PROJECT_DIR}/Libraries/libOCMock.a",
676 | );
677 | PRODUCT_NAME = "$(TARGET_NAME)";
678 | WRAPPER_EXTENSION = octest;
679 | };
680 | name = Release;
681 | };
682 | 9438A14D1593E4410042CA60 /* Debug */ = {
683 | isa = XCBuildConfiguration;
684 | buildSettings = {
685 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
686 | FRAMEWORK_SEARCH_PATHS = (
687 | "$(inherited)",
688 | "\"$(SYSTEM_APPS_DIR)/Xcode44-DP6.app/Contents/Developer/Library/Frameworks\"",
689 | );
690 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
691 | GCC_PREFIX_HEADER = "DemoApp/DemoApp-Prefix.pch";
692 | INFOPLIST_FILE = "DemoApp/DemoApp-Info.plist";
693 | OTHER_LDFLAGS = (
694 | "-ObjC",
695 | "-all_load",
696 | "-framework",
697 | "UITableView+NXEmptyView",
698 | );
699 | PRODUCT_NAME = "$(TARGET_NAME)";
700 | WRAPPER_EXTENSION = app;
701 | };
702 | name = Debug;
703 | };
704 | 9438A14E1593E4410042CA60 /* Release */ = {
705 | isa = XCBuildConfiguration;
706 | buildSettings = {
707 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
708 | FRAMEWORK_SEARCH_PATHS = (
709 | "$(inherited)",
710 | "\"$(SYSTEM_APPS_DIR)/Xcode44-DP6.app/Contents/Developer/Library/Frameworks\"",
711 | );
712 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
713 | GCC_PREFIX_HEADER = "DemoApp/DemoApp-Prefix.pch";
714 | INFOPLIST_FILE = "DemoApp/DemoApp-Info.plist";
715 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
716 | OTHER_LDFLAGS = (
717 | "-ObjC",
718 | "-all_load",
719 | "-framework",
720 | "UITableView+NXEmptyView",
721 | );
722 | PRODUCT_NAME = "$(TARGET_NAME)";
723 | WRAPPER_EXTENSION = app;
724 | };
725 | name = Release;
726 | };
727 | /* End XCBuildConfiguration section */
728 |
729 | /* Begin XCConfigurationList section */
730 | 9438A0FC1593E4110042CA60 /* Build configuration list for PBXProject "UITableView+NXEmptyView" */ = {
731 | isa = XCConfigurationList;
732 | buildConfigurations = (
733 | 9438A1281593E4120042CA60 /* Debug */,
734 | 9438A1291593E4120042CA60 /* Release */,
735 | );
736 | defaultConfigurationIsVisible = 0;
737 | defaultConfigurationName = Release;
738 | };
739 | 9438A12A1593E4120042CA60 /* Build configuration list for PBXNativeTarget "UITableView+NXEmptyView" */ = {
740 | isa = XCConfigurationList;
741 | buildConfigurations = (
742 | 9438A12B1593E4120042CA60 /* Debug */,
743 | 9438A12C1593E4120042CA60 /* Release */,
744 | );
745 | defaultConfigurationIsVisible = 0;
746 | defaultConfigurationName = Release;
747 | };
748 | 9438A12D1593E4120042CA60 /* Build configuration list for PBXNativeTarget "UITableView+NXEmptyViewTests" */ = {
749 | isa = XCConfigurationList;
750 | buildConfigurations = (
751 | 9438A12E1593E4120042CA60 /* Debug */,
752 | 9438A12F1593E4120042CA60 /* Release */,
753 | );
754 | defaultConfigurationIsVisible = 0;
755 | defaultConfigurationName = Release;
756 | };
757 | 9438A14C1593E4410042CA60 /* Build configuration list for PBXNativeTarget "DemoApp" */ = {
758 | isa = XCConfigurationList;
759 | buildConfigurations = (
760 | 9438A14D1593E4410042CA60 /* Debug */,
761 | 9438A14E1593E4410042CA60 /* Release */,
762 | );
763 | defaultConfigurationIsVisible = 0;
764 | defaultConfigurationName = Release;
765 | };
766 | /* End XCConfigurationList section */
767 | };
768 | rootObject = 9438A0F91593E4110042CA60 /* Project object */;
769 | }
770 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyView/UITableView+NXEmptyView-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | com.nxtbgthng.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | FMWK
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | NSPrincipalClass
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyView/UITableView+NXEmptyView-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'UITableView+NXEmptyView' target in the 'UITableView+NXEmptyView' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #endif
8 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyView/UITableView+NXEmptyView.h:
--------------------------------------------------------------------------------
1 | //
2 | // UITableView+NXEmptyView.h
3 | // TableWithEmptyView
4 | //
5 | // Created by Ullrich Schäfer on 21.06.12.
6 | //
7 | //
8 |
9 | #import
10 |
11 | @interface UITableView (NXEmptyView)
12 |
13 | @property (nonatomic, strong) IBOutlet UIView *nxEV_emptyView;
14 | @property (nonatomic, assign) BOOL nxEV_hideSeparatorLinesWhenShowingEmptyView;
15 |
16 | @end
17 |
18 |
19 | @protocol UITableViewNXEmptyViewDataSource
20 | @optional
21 | - (BOOL)tableViewShouldBypassNXEmptyView:(UITableView *)tableView;
22 | @end
23 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyView/UITableView+NXEmptyView.m:
--------------------------------------------------------------------------------
1 | //
2 | // UITableView+NXEmptyView.m
3 | // TableWithEmptyView
4 | //
5 | // Created by Ullrich Schäfer on 21.06.12.
6 | //
7 | //
8 |
9 | #import
10 |
11 | #import "UITableView+NXEmptyView.h"
12 |
13 |
14 | static const NSString *NXEmptyViewAssociatedKey = @"NXEmptyViewAssociatedKey";
15 | static const NSString *NXEmptyViewHideSeparatorLinesAssociatedKey = @"NXEmptyViewHideSeparatorLinesAssociatedKey";
16 | static const NSString *NXEmptyViewPreviousSeparatorStyleAssociatedKey = @"NXEmptyViewPreviousSeparatorStyleAssociatedKey";
17 |
18 |
19 | void nxEV_swizzle(Class c, SEL orig, SEL new)
20 | {
21 | Method origMethod = class_getInstanceMethod(c, orig);
22 | Method newMethod = class_getInstanceMethod(c, new);
23 | if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
24 | class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
25 | else
26 | method_exchangeImplementations(origMethod, newMethod);
27 | }
28 |
29 |
30 |
31 | @interface UITableView (NXEmptyViewPrivate)
32 | @property (nonatomic, assign) UITableViewCellSeparatorStyle nxEV_previousSeparatorStyle;
33 | @end
34 |
35 |
36 | @implementation UITableView (NXEmptyView)
37 |
38 | #pragma mark Entry
39 |
40 | + (void)load;
41 | {
42 | Class c = [UITableView class];
43 | nxEV_swizzle(c, @selector(reloadData), @selector(nxEV_reloadData));
44 | nxEV_swizzle(c, @selector(layoutSubviews), @selector(nxEV_layoutSubviews));
45 | }
46 |
47 | #pragma mark Properties
48 |
49 | - (BOOL)nxEV_hasRowsToDisplay;
50 | {
51 | NSUInteger numberOfRows = 0;
52 | for (NSInteger sectionIndex = 0; sectionIndex < self.numberOfSections; sectionIndex++) {
53 | numberOfRows += [self numberOfRowsInSection:sectionIndex];
54 | }
55 | return (numberOfRows > 0);
56 | }
57 |
58 | @dynamic nxEV_emptyView;
59 | - (UIView *)nxEV_emptyView;
60 | {
61 | return objc_getAssociatedObject(self, &NXEmptyViewAssociatedKey);
62 | }
63 |
64 | - (void)setNxEV_emptyView:(UIView *)value;
65 | {
66 | if (self.nxEV_emptyView.superview) {
67 | [self.nxEV_emptyView removeFromSuperview];
68 | }
69 | objc_setAssociatedObject(self, &NXEmptyViewAssociatedKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
70 | [self nxEV_updateEmptyView];
71 | }
72 |
73 | @dynamic nxEV_hideSeparatorLinesWhenShowingEmptyView;
74 | - (BOOL)nxEV_hideSeparatorLinesWhenShowingEmptyView
75 | {
76 | NSNumber *hideSeparator = objc_getAssociatedObject(self, &NXEmptyViewHideSeparatorLinesAssociatedKey);
77 | return hideSeparator ? [hideSeparator boolValue] : NO;
78 | }
79 |
80 | - (void)setNxEV_hideSeparatorLinesWhenShowingEmptyView:(BOOL)value
81 | {
82 | NSNumber *hideSeparator = [NSNumber numberWithBool:value];
83 | objc_setAssociatedObject(self, &NXEmptyViewHideSeparatorLinesAssociatedKey, hideSeparator, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
84 | }
85 |
86 |
87 | #pragma mark Updating
88 |
89 | - (void)nxEV_updateEmptyView;
90 | {
91 | UIView *emptyView = self.nxEV_emptyView;
92 |
93 | if (!emptyView) return;
94 |
95 | if (emptyView.superview != self) {
96 | [self addSubview:emptyView];
97 | }
98 |
99 | // setup empty view frame
100 | CGRect frame = self.bounds;
101 | frame.origin = CGPointMake(0, 0);
102 | frame = UIEdgeInsetsInsetRect(frame, UIEdgeInsetsMake(CGRectGetHeight(self.tableHeaderView.frame), 0, 0, 0));
103 | frame.size.height -= self.contentInset.top;
104 | emptyView.frame = frame;
105 | emptyView.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
106 |
107 | // check available data
108 | BOOL emptyViewShouldBeShown = (self.nxEV_hasRowsToDisplay == NO);
109 |
110 | // check bypassing
111 | if (emptyViewShouldBeShown && [self.dataSource respondsToSelector:@selector(tableViewShouldBypassNXEmptyView:)]) {
112 | BOOL emptyViewShouldBeBypassed = [(id)self.dataSource tableViewShouldBypassNXEmptyView:self];
113 | emptyViewShouldBeShown &= !emptyViewShouldBeBypassed;
114 | }
115 |
116 | // hide tableView separators, if present
117 | if (self.nxEV_hideSeparatorLinesWhenShowingEmptyView) {
118 | if (emptyViewShouldBeShown) {
119 | if (self.separatorStyle != UITableViewCellSeparatorStyleNone) {
120 | self.nxEV_previousSeparatorStyle = self.separatorStyle;
121 | self.separatorStyle = UITableViewCellSeparatorStyleNone;
122 | }
123 | } else {
124 | if (self.separatorStyle != self.nxEV_previousSeparatorStyle) {
125 | // we've seen an issue with the separator color not being correct when setting separator style during layoutSubviews
126 | // that's why we schedule the call on the next runloop cycle
127 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
128 | self.separatorStyle = self.nxEV_previousSeparatorStyle;
129 | });
130 |
131 | }
132 | }
133 | }
134 |
135 | // show / hide empty view
136 | emptyView.hidden = !emptyViewShouldBeShown;
137 | }
138 |
139 |
140 | #pragma mark Swizzle methods
141 |
142 | - (void)nxEV_reloadData;
143 | {
144 | // this calls the original reloadData implementation
145 | [self nxEV_reloadData];
146 |
147 | [self nxEV_updateEmptyView];
148 | }
149 |
150 | - (void)nxEV_layoutSubviews;
151 | {
152 | // this calls the original layoutSubviews implementation
153 | [self nxEV_layoutSubviews];
154 |
155 | [self nxEV_updateEmptyView];
156 | }
157 |
158 | @end
159 |
160 |
161 | #pragma mark Private
162 | #pragma mark -
163 |
164 | @implementation UITableView (NXEmptyViewPrivate)
165 |
166 | @dynamic nxEV_previousSeparatorStyle;
167 | - (UITableViewCellSeparatorStyle)nxEV_previousSeparatorStyle
168 | {
169 | NSNumber *previousSeparatorStyle = objc_getAssociatedObject(self, &NXEmptyViewPreviousSeparatorStyleAssociatedKey);
170 | return previousSeparatorStyle ? [previousSeparatorStyle intValue] : self.separatorStyle;
171 | }
172 |
173 | - (void)setNxEV_previousSeparatorStyle:(UITableViewCellSeparatorStyle)value
174 | {
175 | NSNumber *previousSeparatorStyle = [NSNumber numberWithInt:value];
176 | objc_setAssociatedObject(self, &NXEmptyViewPreviousSeparatorStyleAssociatedKey, previousSeparatorStyle, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
177 | }
178 |
179 | @end
180 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyView/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyViewTests/UITableView+NXEmptyViewTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.nxtbgthng.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyViewTests/UITableView_NXEmptyViewTests.h:
--------------------------------------------------------------------------------
1 | //
2 | // UITableView_NXEmptyViewTests.h
3 | // UITableView+NXEmptyViewTests
4 | //
5 | // Created by Ullrich Schäfer on 21.06.12.
6 | // Copyright (c) 2012 nxtbgthng.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import
12 | #import
13 |
14 | @interface UITableView_NXEmptyViewTests : SenTestCase
15 |
16 | @property (nonatomic, retain) UITableView *tableView;
17 | @property (nonatomic, retain) OCMockObject *dataSourceMock;
18 |
19 | @property (nonatomic, retain) NSArray *dataSourceItems;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyViewTests/UITableView_NXEmptyViewTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // UITableView_NXEmptyViewTests.m
3 | // UITableView+NXEmptyViewTests
4 | //
5 | // Created by Ullrich Schäfer on 21.06.12.
6 | // Copyright (c) 2012 nxtbgthng.com. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | #import "UITableView_NXEmptyViewTests.h"
13 |
14 | @implementation UITableView_NXEmptyViewTests
15 |
16 | - (void)setUp
17 | {
18 | [super setUp];
19 |
20 | self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 100, 100) style:UITableViewStylePlain];
21 | self.tableView.nxEV_emptyView = [[UIView alloc] initWithFrame:CGRectZero];
22 |
23 | self.dataSourceMock = [OCMockObject niceMockForProtocol:@protocol(UITableViewNXEmptyViewDataSource)];
24 | self.tableView.dataSource = self.dataSourceMock;
25 |
26 | // configuring the database mock
27 | UITableViewCell *dummyCell = [OCMockObject niceMockForClass:[UITableViewCell class]];
28 | NSInteger sections = 1; // this needs to be in a seperate variable for OCMOCK_VALUE to work
29 |
30 | [[[self.dataSourceMock stub] andReturn:dummyCell] tableView:OCMOCK_ANY cellForRowAtIndexPath:OCMOCK_ANY];
31 | [[[self.dataSourceMock stub] andReturnValue:OCMOCK_VALUE(sections)] numberOfSectionsInTableView:OCMOCK_ANY];
32 |
33 | // dynamically get the number of rows from dataSourceItems
34 | __block id blockSelf = self;
35 | void(^numberOfRowsBlock)(NSInvocation *) = ^(NSInvocation *i) {
36 | NSInteger rowCount = [[blockSelf dataSourceItems] count];
37 | [i setReturnValue:&rowCount];
38 | };
39 | [[[self.dataSourceMock stub] andDo:numberOfRowsBlock] tableView:OCMOCK_ANY numberOfRowsInSection:0];
40 | }
41 |
42 | - (void)tearDown
43 | {
44 | self.tableView = nil;
45 | self.dataSourceMock = nil;
46 | [super tearDown];
47 | }
48 |
49 | #pragma mark -
50 | #pragma mark Tests
51 |
52 | - (void)testTheMocking
53 | {
54 | self.dataSourceItems = [NSArray arrayWithObject:@"x"];
55 | [self.tableView reloadData];
56 | STAssertEquals([self.tableView numberOfRowsInSection:0], 1, @"Better check the mocking of the tests (1)");
57 |
58 | self.dataSourceItems = [NSArray array];
59 | [self.tableView reloadData];
60 | STAssertEquals([self.tableView numberOfRowsInSection:0], 0, @"Better check the mocking of the tests (2)");
61 | }
62 |
63 | - (void)testForNilEmptyView
64 | {
65 | self.dataSourceItems = [NSArray arrayWithObject:@"x"];
66 | [self.tableView reloadData];
67 | STAssertTrue([self.tableView numberOfRowsInSection:0] > 0, @"There should be cells in the table view");
68 | STAssertNotNil(self.tableView.nxEV_emptyView, @"There should be an empty view");
69 | STAssertNil(self.tableView.nxEV_emptyView.superview, @"The empty view should not be visible");
70 | }
71 |
72 | - (void)testForEmptyView
73 | {
74 | self.dataSourceItems = [NSArray array];
75 | [self.tableView reloadData];
76 | STAssertTrue([self.tableView numberOfRowsInSection:0] == 0, @"There should be no cells in the table view");
77 | STAssertNotNil(self.tableView.nxEV_emptyView, @"There should be an empty view");
78 | STAssertNotNil(self.tableView.nxEV_emptyView.superview, @"The empty view should be visible");
79 | }
80 |
81 | - (void)testThatTheFrameOfTheEmptyViewIsSetCorrectly
82 | {
83 | [self.tableView reloadData];
84 | STAssertNotNil(self.tableView.nxEV_emptyView, @"There should be an empty view");
85 | STAssertNotNil(self.tableView.nxEV_emptyView.superview, @"The empty view should be visible");
86 | STAssertTrue(CGRectEqualToRect(self.tableView.nxEV_emptyView.frame, self.tableView.bounds), @"The frame of the emptyView should be the bounds of the table view");
87 | }
88 |
89 | - (void)testThatTheFrameOfTheEmptyViewIsUpdatedTogetherWithTheTableView
90 | {
91 | [self.tableView reloadData];
92 | STAssertNotNil(self.tableView.nxEV_emptyView, @"There should be an empty view");
93 | STAssertNotNil(self.tableView.nxEV_emptyView.superview, @"The empty view should be visible");
94 | STAssertTrue(CGRectEqualToRect(self.tableView.nxEV_emptyView.frame, self.tableView.bounds), @"The frame of the emptyView should be the bounds of the table view");
95 | self.tableView.frame = CGRectMake(10, 10, 200, 200);
96 | STAssertTrue(CGRectEqualToRect(self.tableView.nxEV_emptyView.frame, self.tableView.bounds), @"The frame of the emptyView should be the bounds of the table view, even after updating and not %@", NSStringFromCGRect(self.tableView.nxEV_emptyView.frame));
97 | }
98 |
99 | - (void)testBypassingOfTheEmptyView
100 | {
101 | [self.tableView reloadData];
102 | STAssertNotNil(self.tableView.nxEV_emptyView, @"There should be an empty view");
103 | STAssertNotNil(self.tableView.nxEV_emptyView.superview, @"The empty view should be visible");
104 |
105 | BOOL shouldBypassEmptyView = YES;
106 | [[[self.dataSourceMock stub] andReturnValue:OCMOCK_VALUE(shouldBypassEmptyView)] tableViewShouldBypassNXEmptyView:OCMOCK_ANY];
107 | [self.tableView reloadData];
108 |
109 | STAssertNotNil(self.tableView.nxEV_emptyView, @"There should be an empty view");
110 | STAssertNil(self.tableView.nxEV_emptyView.superview, @"The empty view should not be visible");
111 | }
112 |
113 | - (void)testTableViewShouldStillWorkWithDefaultDatasourceProtocol
114 | {
115 | id plainDataSource = [OCMockObject niceMockForProtocol:@protocol(UITableViewDataSource)];
116 | [[[plainDataSource stub] andReturnValue:[NSNumber numberWithInteger:0]] tableView:OCMOCK_ANY numberOfRowsInSection:0];
117 | self.tableView.dataSource = plainDataSource;
118 | [self.tableView reloadData];
119 | STAssertNotNil(self.tableView.nxEV_emptyView, @"There should be an empty view");
120 | STAssertNotNil(self.tableView.nxEV_emptyView.superview, @"The empty view should be visible");
121 | }
122 |
123 | - (void)testEmptyViewShouldScrollWithTableView
124 | {
125 | [self.tableView reloadData];
126 | STAssertNotNil(self.tableView.nxEV_emptyView, @"There should be an empty view");
127 | STAssertTrue(CGPointEqualToPoint(self.tableView.nxEV_emptyView.frame.origin, CGPointZero), @"Empty view should be positioned correctly");
128 |
129 | [self.tableView setContentOffset:CGPointMake(0, 40)];
130 | // needs the layout subviews here, because setContentOffset is just calling setNeedsLayout and we don't want
131 | // to add asynchrony to the test :)
132 | [self.tableView layoutSubviews];
133 |
134 | STAssertTrue(CGPointEqualToPoint(self.tableView.nxEV_emptyView.frame.origin, CGPointZero), @"Empty view should be positioned correctly");
135 | }
136 |
137 | - (void)testTableViewShouldNotHideSeparatorLinesWhenShowingEmptyView
138 | {
139 | self.dataSourceItems = [NSArray arrayWithObject:@"x"];
140 | [self.tableView reloadData];
141 | UITableViewCellSeparatorStyle separatorStyle = self.tableView.separatorStyle;
142 |
143 | STAssertTrue(self.tableView.separatorStyle == UITableViewCellSeparatorStyleSingleLine, @"Default separator style should be present");
144 |
145 | self.dataSourceItems = [NSArray array];
146 | [self.tableView reloadData];
147 |
148 | STAssertTrue(self.tableView.separatorStyle == separatorStyle, @"Separator style should not change when empty view is shown");
149 | }
150 |
151 | - (void)testTableViewShouldHideSeparatorLinesWhenShowingEmptyViewWhenRequested
152 | {
153 | self.tableView.nxEV_hideSeparatorLinesWhenShowingEmptyView = YES;
154 |
155 | self.dataSourceItems = [NSArray arrayWithObject:@"x"];
156 | [self.tableView reloadData];
157 | UITableViewCellSeparatorStyle separatorStyle = self.tableView.separatorStyle;
158 |
159 | self.dataSourceItems = [NSArray array];
160 | [self.tableView reloadData];
161 |
162 | STAssertTrue(self.tableView.separatorStyle == UITableViewCellSeparatorStyleNone, @"Separator should be hidden");
163 |
164 | self.dataSourceItems = [NSArray arrayWithObject:@"x"];
165 | [self.tableView reloadData];
166 |
167 | STAssertTrue(self.tableView.separatorStyle == separatorStyle, @"Separator should reappear");
168 | }
169 |
170 | - (void)testEmptyViewShouldRespectTableHeaderView
171 | {
172 | [self.tableView reloadData];
173 | self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
174 | [self.tableView layoutSubviews];
175 |
176 | STAssertTrue(CGPointEqualToPoint(self.tableView.nxEV_emptyView.frame.origin, CGPointMake(0, 50)), @"Empty view should be positioned correctly");
177 | }
178 |
179 | @end
180 |
--------------------------------------------------------------------------------
/UITableView+NXEmptyViewTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/UITableView-NXEmptyView.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'UITableView-NXEmptyView'
3 | s.platform = :ios
4 | s.version = '0.1.7'
5 | s.license = 'BSD'
6 | s.summary = 'A category on UITableView that adds an empty view that can be shown whenever the table view has no cells.'
7 | s.homepage = 'https://github.com/nxtbgthng/UITableView-NXEmptyView'
8 | s.author = { 'nxtbgthng' => 'team@nxtbgthng.com'}
9 | s.source = { :git => 'https://github.com/nxtbgthng/UITableView-NXEmptyView.git',
10 | :tag => "v#{s.version}" }
11 | s.source_files = 'UITableView+NXEmptyView/UITableView+NXEmptyView.h', 'UITableView+NXEmptyView/UITableView+NXEmptyView.m'
12 | s.frameworks = 'UIKit'
13 | s.requires_arc = true
14 | end
15 |
--------------------------------------------------------------------------------