From 8f7c43b303ee8441cd22e7a8cd19d8f7406a10fd Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Dec 2013 09:25:51 -0800 Subject: [PATCH 1/3] #376 - added activity indicator during syncing of empty list views --- WordPress/Classes/UIView+Subviews.h | 15 +++++++ WordPress/Classes/UIView+Subviews.m | 24 ++++++++++ WordPress/Classes/WPTableViewController.m | 45 +++++++++++++++---- WordPress/WordPress.xcodeproj/project.pbxproj | 6 +++ 4 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 WordPress/Classes/UIView+Subviews.h create mode 100644 WordPress/Classes/UIView+Subviews.m diff --git a/WordPress/Classes/UIView+Subviews.h b/WordPress/Classes/UIView+Subviews.h new file mode 100644 index 000000000000..670d8c6b5f04 --- /dev/null +++ b/WordPress/Classes/UIView+Subviews.h @@ -0,0 +1,15 @@ +// +// UIView+Subviews.h +// WordPress +// +// Created by Tom Witkin on 12/6/13. +// Copyright (c) 2013 WordPress. All rights reserved. +// + +#import + +@interface UIView (Subviews) + +- (void)addSubviewWithFadeAnimation:(UIView *)subview; + +@end diff --git a/WordPress/Classes/UIView+Subviews.m b/WordPress/Classes/UIView+Subviews.m new file mode 100644 index 000000000000..e46bcdcd1f27 --- /dev/null +++ b/WordPress/Classes/UIView+Subviews.m @@ -0,0 +1,24 @@ +// +// UIView+Subviews.m +// WordPress +// +// Created by Tom Witkin on 12/6/13. +// Copyright (c) 2013 WordPress. All rights reserved. +// + +#import "UIView+Subviews.h" + +@implementation UIView (Subviews) + +- (void)addSubviewWithFadeAnimation:(UIView *)subview { + + CGFloat finalAlpha = subview.alpha; + + subview.alpha = 0.0; + [self addSubview:subview]; + [UIView animateWithDuration:0.2 animations:^{ + subview.alpha = finalAlpha; + }]; +} + +@end diff --git a/WordPress/Classes/WPTableViewController.m b/WordPress/Classes/WPTableViewController.m index be8b66d0ee7f..9a7feb70b875 100644 --- a/WordPress/Classes/WPTableViewController.m +++ b/WordPress/Classes/WPTableViewController.m @@ -14,6 +14,7 @@ #import "WPNoResultsView.h" #import "SupportViewController.h" #import "ContextManager.h" +#import "UIView+Subviews.h" NSTimeInterval const WPTableViewControllerRefreshTimeout = 300; // 5 minutes CGFloat const WPTableViewTopMargin = 40; @@ -27,6 +28,7 @@ @interface WPTableViewController () @property (nonatomic, strong, readonly) UIView *swipeView; @property (nonatomic, strong) UITableViewCell *swipeCell; @property (nonatomic, strong) UIView *noResultsView; +@property (nonatomic, strong) UIActivityIndicatorView *noResultsAcitivtyIndicator; @end @@ -568,15 +570,32 @@ - (void)configureNoResultsView { } [self.noResultsView removeFromSuperview]; + [self.noResultsAcitivtyIndicator stopAnimating]; + [self.noResultsAcitivtyIndicator removeFromSuperview]; - if (self.resultsController && [[_resultsController fetchedObjects] count] == 0 && !self.isSyncing) { - // Show no results view. - - if (self.noResultsView == nil) { - self.noResultsView = [self createNoResultsView]; - } - - [self.tableView addSubview:self.noResultsView]; + if (self.resultsController && [[_resultsController fetchedObjects] count] == 0) { + + if (self.isSyncing) { + // Show activity indicator view when syncing is occuring + // and the fetched results controller has no objects + if (self.noResultsAcitivtyIndicator == nil) { + self.noResultsAcitivtyIndicator = [self createNoResultsActivityIndicator]; + } + + [self.noResultsAcitivtyIndicator startAnimating]; + [self.tableView addSubview:self.noResultsAcitivtyIndicator]; + + } else { + // Show no results view if the fetched results controller + // has no objects and syncing is not happening. + + if (self.noResultsView == nil) { + self.noResultsView = [self createNoResultsView]; + } + + [self.tableView addSubviewWithFadeAnimation:self.noResultsView]; + } + } } @@ -588,6 +607,16 @@ - (UIView *)createNoResultsView { return view; } +- (UIActivityIndicatorView *)createNoResultsActivityIndicator { + + UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + activityIndicator.hidesWhenStopped = YES; + activityIndicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; + activityIndicator.center = [self.tableView convertPoint:self.tableView.center fromView:self.tableView.superview]; + + return activityIndicator; +} + - (void)hideRefreshHeader { [self.refreshControl endRefreshing]; didTriggerRefresh = NO; diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index 5c950fc3a8c4..f2df8c38a455 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -953,6 +953,7 @@ E2586BD41832F31D004B5B67 /* icon-site-field.png in Resources */ = {isa = PBXBuildFile; fileRef = E2586BD21832F31D004B5B67 /* icon-site-field.png */; }; E2AA879D1850F91E00886693 /* icon-jetpack-gray.png in Resources */ = {isa = PBXBuildFile; fileRef = E2AA879B1850F91E00886693 /* icon-jetpack-gray.png */; }; E2AA879E1850F91E00886693 /* icon-jetpack-gray@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E2AA879C1850F91E00886693 /* icon-jetpack-gray@2x.png */; }; + E2AA87A518523E5300886693 /* UIView+Subviews.m in Sources */ = {isa = PBXBuildFile; fileRef = E2AA87A418523E5300886693 /* UIView+Subviews.m */; }; EC4696FF0EA75D460040EE8E /* PagesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EC4696FE0EA75D460040EE8E /* PagesViewController.m */; }; FD21397F13128C5300099582 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FD21397E13128C5300099582 /* libiconv.dylib */; }; FD22C2B716CD2B20002BA030 /* navbar_settings.png in Resources */ = {isa = PBXBuildFile; fileRef = FD22C2B516CD2B20002BA030 /* navbar_settings.png */; }; @@ -2134,6 +2135,8 @@ E2586BD21832F31D004B5B67 /* icon-site-field.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-site-field.png"; sourceTree = ""; }; E2AA879B1850F91E00886693 /* icon-jetpack-gray.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-jetpack-gray.png"; path = "Resources/Images/icon-jetpack-gray.png"; sourceTree = ""; }; E2AA879C1850F91E00886693 /* icon-jetpack-gray@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-jetpack-gray@2x.png"; path = "Resources/Images/icon-jetpack-gray@2x.png"; sourceTree = ""; }; + E2AA87A318523E5300886693 /* UIView+Subviews.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Subviews.h"; sourceTree = ""; }; + E2AA87A418523E5300886693 /* UIView+Subviews.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Subviews.m"; sourceTree = ""; }; EBC24772E5CD4036B5AFD803 /* Pods.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.xcconfig; path = ../Pods/Pods.xcconfig; sourceTree = SOURCE_ROOT; }; EC4696FD0EA75D460040EE8E /* PagesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PagesViewController.h; sourceTree = ""; }; EC4696FE0EA75D460040EE8E /* PagesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PagesViewController.m; sourceTree = ""; }; @@ -3706,6 +3709,8 @@ 851734421798C64700A30E27 /* NSURL+Util.m */, 46F8714D1838C41600BC149B /* NSDate+StringFormatting.h */, 46F8714E1838C41600BC149B /* NSDate+StringFormatting.m */, + E2AA87A318523E5300886693 /* UIView+Subviews.h */, + E2AA87A418523E5300886693 /* UIView+Subviews.m */, ); name = Categories; sourceTree = ""; @@ -4971,6 +4976,7 @@ 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 1D3623260D0F684500981E51 /* WordPressAppDelegate.m in Sources */, 2F970F740DF92274006BD934 /* PostsViewController.m in Sources */, + E2AA87A518523E5300886693 /* UIView+Subviews.m in Sources */, 93C486511810445D00A24725 /* ActivityLogViewController.m in Sources */, ACC156CC0E10E67600D6E1A0 /* EditPostViewController.m in Sources */, ACBAB5FE0E121C7300F38795 /* PostSettingsViewController.m in Sources */, From c2b56195d36a87a9a1e53cec205eb9b42b2d7787 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Dec 2013 09:31:08 -0800 Subject: [PATCH 2/3] Removed extra whitespace --- WordPress/Classes/WPTableViewController.m | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/WordPress/Classes/WPTableViewController.m b/WordPress/Classes/WPTableViewController.m index 9a7feb70b875..d34919e56492 100644 --- a/WordPress/Classes/WPTableViewController.m +++ b/WordPress/Classes/WPTableViewController.m @@ -574,17 +574,16 @@ - (void)configureNoResultsView { [self.noResultsAcitivtyIndicator removeFromSuperview]; if (self.resultsController && [[_resultsController fetchedObjects] count] == 0) { - if (self.isSyncing) { // Show activity indicator view when syncing is occuring // and the fetched results controller has no objects + if (self.noResultsAcitivtyIndicator == nil) { self.noResultsAcitivtyIndicator = [self createNoResultsActivityIndicator]; } [self.noResultsAcitivtyIndicator startAnimating]; [self.tableView addSubview:self.noResultsAcitivtyIndicator]; - } else { // Show no results view if the fetched results controller // has no objects and syncing is not happening. @@ -592,10 +591,8 @@ - (void)configureNoResultsView { if (self.noResultsView == nil) { self.noResultsView = [self createNoResultsView]; } - [self.tableView addSubviewWithFadeAnimation:self.noResultsView]; } - } } From b0347bc5b21e6885a152114876c03806103bb768 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Dec 2013 10:39:45 -0800 Subject: [PATCH 3/3] Fixed typo --- WordPress/Classes/WPTableViewController.m | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/WordPress/Classes/WPTableViewController.m b/WordPress/Classes/WPTableViewController.m index d34919e56492..583495384de8 100644 --- a/WordPress/Classes/WPTableViewController.m +++ b/WordPress/Classes/WPTableViewController.m @@ -28,7 +28,7 @@ @interface WPTableViewController () @property (nonatomic, strong, readonly) UIView *swipeView; @property (nonatomic, strong) UITableViewCell *swipeCell; @property (nonatomic, strong) UIView *noResultsView; -@property (nonatomic, strong) UIActivityIndicatorView *noResultsAcitivtyIndicator; +@property (nonatomic, strong) UIActivityIndicatorView *noResultsActivityIndicator; @end @@ -570,20 +570,20 @@ - (void)configureNoResultsView { } [self.noResultsView removeFromSuperview]; - [self.noResultsAcitivtyIndicator stopAnimating]; - [self.noResultsAcitivtyIndicator removeFromSuperview]; + [self.noResultsActivityIndicator stopAnimating]; + [self.noResultsActivityIndicator removeFromSuperview]; if (self.resultsController && [[_resultsController fetchedObjects] count] == 0) { if (self.isSyncing) { // Show activity indicator view when syncing is occuring // and the fetched results controller has no objects - if (self.noResultsAcitivtyIndicator == nil) { - self.noResultsAcitivtyIndicator = [self createNoResultsActivityIndicator]; + if (self.noResultsActivityIndicator == nil) { + self.noResultsActivityIndicator = [self createNoResultsActivityIndicator]; } - [self.noResultsAcitivtyIndicator startAnimating]; - [self.tableView addSubview:self.noResultsAcitivtyIndicator]; + [self.noResultsActivityIndicator startAnimating]; + [self.tableView addSubview:self.noResultsActivityIndicator]; } else { // Show no results view if the fetched results controller // has no objects and syncing is not happening.