Show a search bar in the folder view controller, when there is at least one object. In iPad the search bar is fixed at the top, while in iPhone it is on the top of the tableview, and scrolled off screen initially. Improve the Folder model class and other relevant code.
if ([folderViewController.folder isEqual:container.rootFolder]) {
currentFolderIsRoot = YES;
}
- [folder.folders setObject:newFolder forKey:newFolder.name];
+ [folder addFolder:newFolder];
[folderViewController.tableView reloadData];
+ folderViewController.folder = folderViewController.folder;
if (currentFolderIsRoot) {
container.count += 1;
container.rootFolder = folder;
if ([folderViewController.folder isEqual:container.rootFolder]) {
currentFolderIsRoot = YES;
}
- [folder.objects setObject:object forKey:object.name];
+ [folder addObject:object];
[folderViewController.tableView reloadData];
+ folderViewController.folder = folderViewController.folder;
if (currentFolderIsRoot) {
container.count += 1;
container.rootFolder = folder;
cell.textLabel.text = @"Delete Container";
}
if ((self.container.count == 0) ||
- (self.container.rootFolder && ([self.container.rootFolder.folders count] + [self.container.rootFolder.objects count] == 0))) {
+ (self.container.rootFolder && !self.container.rootFolder.objectsAndFoldersCount)) {
cell.textLabel.textColor = [UIColor blackColor];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
} else {
[vc release];
}
} else if (indexPath.section == deleteSection) {
- if (self.container.count == 0 || ([self.container.rootFolder.folders count] + [self.container.rootFolder.objects count] == 0)) {
+ if (self.container.count == 0 || !self.container.rootFolder.objectsAndFoldersCount) {
UIActionSheet *deleteActionSheet = [[[UIActionSheet alloc] initWithTitle:@"Are you sure you want to delete this container? This operation cannot be undone."
delegate:self
cancelButtonTitle:@"Cancel"
FolderViewController *vc = [[FolderViewController alloc] initWithNibName:@"FolderViewController" bundle:nil];
vc.account = self.account;
vc.container = container;
- vc.folder = container.rootFolder;
vc.containersViewController = self;
vc.selectedContainerIndexPath = indexPath;
[self.navigationController pushViewController:vc animated:YES];
+ vc.folder = container.rootFolder;
[vc release];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
newFolder.parent = folderViewController.folder;
newFolder.sharing = folderViewController.folder.sharing;
newFolder.metadata = object.metadata;
- [folderViewController.folder.folders setObject:newFolder forKey:newFolder.name];
+ [folderViewController.folder addFolder:newFolder];
[activityIndicatorView removeFromSuperview];
[newFolder release];
self.metadataKey = userInputMetaKey;
newFolder.name = [[object.name componentsSeparatedByString:@"/"] lastObject];
newFolder.parent = folderViewController.folder;
newFolder.sharing = folderViewController.folder.sharing;
- [folderViewController.folder.folders setObject:newFolder forKey:newFolder.name];
+ [folderViewController.folder addFolder:newFolder];
[activityIndicatorView removeFromSuperview];
[newFolder release];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
// 3. folder/def.txt
// In this case, there would be a folder object for files 2 and 3
+@class StorageObject;
+
@interface Folder : NSObject <NSCoding> {
NSString *name;
Folder *parent;
@property (nonatomic, retain) NSMutableDictionary *metadata;
@property (nonatomic, retain) NSString *contentType;
+@property (nonatomic, readonly) NSUInteger objectsAndFoldersCount;
+
+ (id)folder;
- (NSArray *)sortedContents;
- (NSString *)fullPath;
+- (void)addFolder:(Folder *)aFolder;
+- (void)addObject:(StorageObject *)anObject;
+- (void)removeFolder:(Folder *)aFolder;
+- (void)removeObject:(StorageObject *)anObject;
@end
@implementation Folder
-@synthesize name, parent, objects, folders, sharing, metadata, contentType;
+@synthesize name, parent, objects, folders, sharing, metadata, contentType, objectsAndFoldersCount;
#pragma mark - Object lifecycle
return sortedContents;
}
+- (NSUInteger)objectsAndFoldersCount {
+ return (self.objects.count + self.folders.count);
+}
+
#pragma mark - Actions
- (NSString *)fullPath {
}
}
+- (void)addFolder:(Folder *)aFolder {
+ [self.folders setObject:aFolder forKey:aFolder.name];
+ [sortedContents release];
+ sortedContents = nil;
+}
+
+- (void)addObject:(StorageObject *)anObject {
+ [self.objects setObject:anObject forKey:anObject.name];
+ [sortedContents release];
+ sortedContents = nil;
+}
+
+- (void)removeFolder:(Folder *)aFolder {
+ if ([self.folders objectForKey:aFolder.name]) {
+ [self.folders removeObjectForKey:aFolder.name];
+ [sortedContents release];
+ sortedContents = nil;
+ }
+}
+
+- (void)removeObject:(StorageObject *)anObject {
+ if ([self.objects objectForKey:anObject.name]) {
+ [self.objects removeObjectForKey:anObject.name];
+ [sortedContents release];
+ sortedContents = nil;
+ }
+}
+
@end
IBOutlet UITableView *tableView;
IBOutlet UIBarButtonItem *homeButton;
IBOutlet UIBarButtonItem *refreshButton;
+ UISearchBar *searchBar;
+
FolderDetailViewController *folderDetailVC;
StorageObjectViewController *selectedObjectViewController;
}
@property (nonatomic, assign) BOOL refreshWhenAppeared;
@property (nonatomic, retain) IBOutlet UITableView *tableView;
@property (nonatomic, retain) IBOutlet UIBarButtonItem *refreshButton;
+@property (nonatomic, readonly) UISearchBar *searchBar;
@property (nonatomic, assign) FolderDetailViewController *folderDetailVC;
@property (nonatomic, assign) StorageObjectViewController *selectedObjectViewController;
@implementation FolderViewController
-@synthesize account, container, folder, containersViewController, selectedContainerIndexPath, contentsLoaded, parentFolderViewController, selectedFolderIndexPath, tableView, needsRefreshing, folderHasBeenRemoved, refreshWhenAppeared, folderDetailVC, selectedObjectViewController, refreshButton;
+@synthesize account, container, folder, containersViewController, selectedContainerIndexPath, contentsLoaded, parentFolderViewController, selectedFolderIndexPath, tableView, needsRefreshing, folderHasBeenRemoved, refreshWhenAppeared, folderDetailVC, selectedObjectViewController, refreshButton, searchBar;
#pragma mark - View lifecycle
[self refreshButtonPressed:nil];
refreshWhenAppeared = NO;
}
- if (account.shared && ([folder.folders count] + [folder.objects count] == 0)) {
+ if (account.shared && !folder.objectsAndFoldersCount) {
[self.navigationController popViewControllerAnimated:YES];
}
}
[parentFolderViewController release];
[selectedFolderIndexPath release];
[refreshButton release];
+ [searchBar release];
[super dealloc];
}
#pragma mark - Internal
+- (void)showSearchBar:(BOOL)show {
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ if (show && self.searchBar.hidden) {
+ // Add search bar above the tableview
+ CGRect tableViewFrame = self.tableView.frame;
+ tableViewFrame.origin.y += 44.0;
+ tableViewFrame.size.height -= 44.0;
+ self.tableView.frame = tableViewFrame;
+ self.searchBar.hidden = NO;
+ [self.view addSubview:self.searchBar];
+ } else if (!show && !self.searchBar.hidden) {
+ // Remove search bar above the tableview
+ CGRect tableViewFrame = self.tableView.frame;
+ tableViewFrame.origin.y -= 44.0;
+ tableViewFrame.size.height += 44.0;
+ self.tableView.frame = tableViewFrame;
+ [self.searchBar removeFromSuperview];
+ self.searchBar.hidden = YES;
+ }
+ } else {
+ if (show && ![self.tableView.tableHeaderView isEqual:self.searchBar]) {
+ self.searchBar.hidden = NO;
+ self.tableView.tableHeaderView = self.searchBar;
+ self.tableView.contentOffset = CGPointMake(0.0, 44.0);
+ } else if (!show) {
+ self.tableView.tableHeaderView = nil;
+ self.searchBar.hidden = YES;
+ }
+ }
+}
+
- (void)reloadFolderViewControllers {
NSArray *viewControllers = [self.navigationController viewControllers];
folderViewController.folderHasBeenRemoved = YES;
}
}
- if (!self.folder || (account.shared && [folder.folders count] + [folder.objects count] == 0)) {
+ if (!self.folder || (account.shared && !folder.objectsAndFoldersCount)) {
if (needsRefreshing && self.parentFolderViewController) {
self.parentFolderViewController.needsRefreshing = YES;
}
}
}
+#pragma mark - Properties
+
+- (UISearchBar *)searchBar {
+ if (!searchBar) {
+ searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)];
+ searchBar.barStyle = UIBarStyleBlack;
+ searchBar.hidden = YES;
+ }
+ return searchBar;
+}
+
+- (void)setFolder:(Folder *)aFolder {
+ [folder release];
+ folder = [aFolder retain];
+ [self showSearchBar:(self.contentsLoaded && self.folder && self.folder.objectsAndFoldersCount)];
+}
+
#pragma mark - Actions
- (void)setDetailViewController {
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
- return MAX(contentsLoaded ? 1 : 0, [folder.objects count] + [folder.folders count]);
+ return MAX(contentsLoaded ? 1 : 0, folder.objectsAndFoldersCount);
}
- (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
- if ([folder.objects count] + [folder.folders count] == 0) {
+ if (!folder.objectsAndFoldersCount) {
aTableView.scrollEnabled = NO;
aTableView.allowsSelection = NO;
return aTableView.frame.size.height;
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- if ([folder.objects count] + [folder.folders count] == 0) {
+ if (!folder.objectsAndFoldersCount) {
NSString *noFoldersTitle = (self.account.shared || self.account.sharingAccount) ?
@"No shared Files or Folders" : @"No Files or Folders";
NSString *noFoldersSubtitle = (self.account.shared || self.account.sharingAccount || [self.folder.name hasSuffix:@"/"]) ?
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
- if ([folder.objects count] + [folder.folders count] > 0) {
- id item = [self.folder.sortedContents objectAtIndex:indexPath.row];
+ if (folder.objectsAndFoldersCount) {
+ id item = [self.folder.sortedContents objectAtIndex:indexPath.row];
if ([[item class] isEqual:[Folder class]]) {
FolderViewController *vc = [[FolderViewController alloc] initWithNibName:@"FolderViewController" bundle:nil];
vc.account = self.account;
vc.container = self.container;
- vc.folder = item;
- vc.contentsLoaded = YES;
vc.selectedFolderIndexPath = indexPath;
vc.parentFolderViewController = self;
vc.containersViewController = self.containersViewController;
[self.navigationController pushViewController:vc animated:YES];
+ vc.contentsLoaded = YES;
+ vc.folder = item;
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
Folder *folderForDetailView;
[[self.account.manager deleteObject:self.container object:object]
success:^(OpenStackRequest *request) {
if (self.folder.parent) {
- [self.folder.parent.folders removeObjectForKey:self.folder.name];
+ [self.folder.parent removeFolder:self.folder];
} else {
- [self.container.rootFolder.folders removeObjectForKey:self.folder.name];
+ [self.container.rootFolder removeFolder:self.folder];
}
[self.account persist];
[self.navigationController popViewControllerAnimated:YES];
if (self.folder.parent) {
- if ([self.folder.parent.folders count] + [self.folder.parent.objects count] == 0) {
+ if (!self.folder.parent.objectsAndFoldersCount) {
[self.parentFolderViewController.tableView reloadData];
+ self.parentFolderViewController.folder = self.parentFolderViewController.folder;
} else {
[self.parentFolderViewController.tableView selectRowAtIndexPath:selectedFolderIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
[NSTimer scheduledTimerWithTimeInterval:0.75 target:self selector:@selector(deleteFolderRow) userInfo:nil repeats:NO];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
[self.parentFolderViewController setDetailViewController];
} else {
- if ([self.container.rootFolder.folders count] + [self.container.rootFolder.objects count] == 0) {
+ if (!self.container.rootFolder.objectsAndFoldersCount) {
[self.parentFolderViewController.tableView reloadData];
+ self.parentFolderViewController.folder = self.parentFolderViewController.folder;
} else {
[self.parentFolderViewController.tableView selectRowAtIndexPath:selectedFolderIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
[NSTimer scheduledTimerWithTimeInterval:0.75 target:self selector:@selector(deleteFolderRow) userInfo:nil repeats:NO];
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
<data>
- <int key="IBDocument.SystemTarget">1296</int>
- <string key="IBDocument.SystemVersion">11E53</string>
- <string key="IBDocument.InterfaceBuilderVersion">2182</string>
- <string key="IBDocument.AppKitVersion">1138.47</string>
+ <int key="IBDocument.SystemTarget">1536</int>
+ <string key="IBDocument.SystemVersion">11G63</string>
+ <string key="IBDocument.InterfaceBuilderVersion">2843</string>
+ <string key="IBDocument.AppKitVersion">1138.51</string>
<string key="IBDocument.HIToolboxVersion">569.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <string key="NS.object.0">1181</string>
+ <string key="NS.object.0">1929</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <string>IBProxyObject</string>
<string>IBUIBarButtonItem</string>
<string>IBUITableView</string>
<string>IBUIToolbar</string>
<string>IBUIView</string>
- <string>IBProxyObject</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<int key="NSvFlags">266</int>
<string key="NSFrame">{{0, 416}, {320, 44}}</string>
<reference key="NSSuperview" ref="228054471"/>
- <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{320, 416}</string>
<reference key="NSSuperview" ref="228054471"/>
- <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="599029925"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
</object>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview"/>
- <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="173989330"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="173989330"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
<reference key="parent" ref="228054471"/>
<string key="objectName">Table View</string>
</object>
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
- <int key="maxID">28</int>
- </object>
- <object class="IBClassDescriber" key="IBDocument.Classes">
- <object class="NSMutableArray" key="referencedPartialClassDescriptions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBPartialClassDescription">
- <string key="className">FolderViewController</string>
- <string key="superclassName">OpenStackViewController</string>
- <object class="NSMutableDictionary" key="actions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>homeButtonPressed:</string>
- <string>refreshButtonPressed:</string>
- </object>
- <object class="NSArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>id</string>
- <string>id</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="actionInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>homeButtonPressed:</string>
- <string>refreshButtonPressed:</string>
- </object>
- <object class="NSArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBActionInfo">
- <string key="name">homeButtonPressed:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">refreshButtonPressed:</string>
- <string key="candidateClassName">id</string>
- </object>
- </object>
- </object>
- <object class="NSMutableDictionary" key="outlets">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>homeButton</string>
- <string>refreshButton</string>
- <string>tableView</string>
- </object>
- <object class="NSArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>UIBarButtonItem</string>
- <string>UIBarButtonItem</string>
- <string>UITableView</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="toOneOutletInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>homeButton</string>
- <string>refreshButton</string>
- <string>tableView</string>
- </object>
- <object class="NSArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBToOneOutletInfo">
- <string key="name">homeButton</string>
- <string key="candidateClassName">UIBarButtonItem</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">refreshButton</string>
- <string key="candidateClassName">UIBarButtonItem</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">tableView</string>
- <string key="candidateClassName">UITableView</string>
- </object>
- </object>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">./Classes/FolderViewController.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">OpenStackViewController</string>
- <string key="superclassName">UIViewController</string>
- <object class="NSMutableDictionary" key="outlets">
- <string key="NS.key.0">toolbar</string>
- <string key="NS.object.0">UIToolbar</string>
- </object>
- <object class="NSMutableDictionary" key="toOneOutletInfosByName">
- <string key="NS.key.0">toolbar</string>
- <object class="IBToOneOutletInfo" key="NS.object.0">
- <string key="name">toolbar</string>
- <string key="candidateClassName">UIToolbar</string>
- </object>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">./Classes/OpenStackViewController.h</string>
- </object>
- </object>
- </object>
+ <int key="maxID">30</int>
</object>
+ <object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
- <real value="1296" key="NS.object.0"/>
+ <real value="1536" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
- <string key="IBCocoaTouchPluginVersion">1181</string>
+ <string key="IBCocoaTouchPluginVersion">1929</string>
</data>
</archive>
Container *container;
Folder *folder;
StorageObject *object;
- BOOL performingAction;
BOOL fileDownloaded;
AnimatedProgressView *downloadProgressView;
BOOL fileDownloading;
#pragma mark Action Sheet Delegate
- (void)deleteObjectRow {
- [self.folder.objects removeObjectForKey:self.object.name];
+ [self.folder removeObject:self.object];
[self.folderViewController.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:selectedIndexPath] withRowAnimation:UITableViewRowAnimationLeft];
self.folderViewController.refreshButton.enabled = YES;
}
[[self.account.manager deleteObject:self.container object:self.object]
success:^(OpenStackRequest *request) {
[activityIndicatorView removeFromSuperview];
- performingAction = NO;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
[self.navigationController popViewControllerAnimated:YES];
if (account.shared)
[self.folderViewController setDetailViewController];
else
[self.folderViewController refreshButtonPressed:nil];
+ self.folderViewController.refreshButton.enabled = YES;
}
if (self.folder.objects.count == 1)
- [self.folder.objects removeObjectForKey:self.object.name];
+ [self.folder removeObject:self.object];
- if ([self.folder.objects count] + [self.folder.folders count] == 0) {
+ if (!self.folder.objectsAndFoldersCount) {
[self.folderViewController.tableView reloadData];
+ self.folderViewController.folder = self.folderViewController.folder;
} else {
[self.folderViewController.tableView selectRowAtIndexPath:selectedIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
[NSTimer scheduledTimerWithTimeInterval:0.75 target:self selector:@selector(deleteObjectRow) userInfo:nil repeats:NO];
failure:^(OpenStackRequest *request) {
[activityIndicatorView removeFromSuperview];
[self hideToolbarActivityMessage];
- performingAction = NO;
- [self alert:@"There was a problem deleting this file." request:request];
+ [self alert:@"There was a problem deleting this file." request:request];
}];
}
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:deleteSection];
if ([folderViewController.folder isEqual:container.rootFolder]) {
currentFolderIsRoot = YES;
}
- [folder.objects setObject:object forKey:object.name];
+ [folder addObject:object];
[folderViewController.tableView reloadData];
+ folderViewController.folder = folderViewController.folder;
if (currentFolderIsRoot) {
container.count += 1;
container.rootFolder = folder;