Commit 22065f24 authored by sczs@chromium.org's avatar sczs@chromium.org Committed by Commit Bot

[ios] Creates TableViewLoadingView, adds it to HistoryTableVC.

- Creates TableViewLoadingView, which is added as a backgroundView of ChromeTableVC.
- HistoryTableVC adds this TableViewLoadingView instead of implementing its own.
- Re-adds searching property to HistoryTableVC.

Screenshot:
https://drive.google.com/open?id=1gXnkLADyKrv3hqtijU7Su9t8gW0hR7el

Bug: 838577
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: Id494826f4bd522062f7d30bf4c6e7e81ceba6370
Reviewed-on: https://chromium-review.googlesource.com/1041187
Commit-Queue: Sergio Collazos <sczs@chromium.org>
Reviewed-by: default avatarRohit Rao <rohitrao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567095}
parent 64397686
...@@ -82,6 +82,8 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -82,6 +82,8 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
BOOL shouldShowNoticeAboutOtherFormsOfBrowsingHistory; BOOL shouldShowNoticeAboutOtherFormsOfBrowsingHistory;
// YES if there is an outstanding history query. // YES if there is an outstanding history query.
@property(nonatomic, assign, getter=isLoading) BOOL loading; @property(nonatomic, assign, getter=isLoading) BOOL loading;
// YES if there is a search happening.
@property(nonatomic, assign) BOOL searchInProgress;
// YES if there are no more history entries to load. // YES if there are no more history entries to load.
@property(nonatomic, assign, getter=hasFinishedLoading) BOOL finishedLoading; @property(nonatomic, assign, getter=hasFinishedLoading) BOOL finishedLoading;
// YES if the table should be filtered by the next received query result. // YES if the table should be filtered by the next received query result.
...@@ -113,6 +115,7 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -113,6 +115,7 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
@synthesize loading = _loading; @synthesize loading = _loading;
@synthesize localDispatcher = _localDispatcher; @synthesize localDispatcher = _localDispatcher;
@synthesize searchController = _searchController; @synthesize searchController = _searchController;
@synthesize searchInProgress = _searchInProgress;
@synthesize shouldShowNoticeAboutOtherFormsOfBrowsingHistory = @synthesize shouldShowNoticeAboutOtherFormsOfBrowsingHistory =
_shouldShowNoticeAboutOtherFormsOfBrowsingHistory; _shouldShowNoticeAboutOtherFormsOfBrowsingHistory;
@synthesize presentationDelegate = _presentationDelegate; @synthesize presentationDelegate = _presentationDelegate;
...@@ -188,18 +191,10 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -188,18 +191,10 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
- (void)loadModel { - (void)loadModel {
[super loadModel]; [super loadModel];
// Add initial info section as header. // Add Status section, this section will always exist during the lifetime of
// HistoryTableVC. Its content will be driven by |updateEntriesStatusMessage|.
[self.tableViewModel [self.tableViewModel
addSectionWithIdentifier:kEntriesStatusSectionIdentifier]; addSectionWithIdentifier:kEntriesStatusSectionIdentifier];
// TODO(crbug.com/833623): Temporary loading indicator, will update once we
// decide on a standard.
TableViewTextItem* entriesStatusItem =
[[TableViewTextItem alloc] initWithType:ItemTypeEntriesStatus];
entriesStatusItem.text = @"Loading";
entriesStatusItem.textColor = TextItemColorBlack;
[self.tableViewModel addItem:entriesStatusItem
toSectionWithIdentifier:kEntriesStatusSectionIdentifier];
_entryInserter = _entryInserter =
[[HistoryEntryInserter alloc] initWithModel:self.tableViewModel]; [[HistoryEntryInserter alloc] initWithModel:self.tableViewModel];
_entryInserter.delegate = self; _entryInserter.delegate = self;
...@@ -232,6 +227,9 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -232,6 +227,9 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
return; return;
} }
// At this point there has been a response, we can stop the loading indicator.
[self stopLoadingIndicatorWithCompletion:nil];
// If there are no results and no URLs have been loaded, report that no // If there are no results and no URLs have been loaded, report that no
// history entries were found. // history entries were found.
if (results.empty() && self.empty) { if (results.empty() && self.empty) {
...@@ -269,7 +267,7 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -269,7 +267,7 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
[self updateToolbarButtons]; [self updateToolbarButtons];
if ((self.searchController.isActive && [searchQuery length] > 0 && if ((self.searchInProgress && [searchQuery length] > 0 &&
[self.currentQuery isEqualToString:searchQuery]) || [self.currentQuery isEqualToString:searchQuery]) ||
self.filterQueryResult) { self.filterQueryResult) {
// If in search mode, filter out entries that are not part of the // If in search mode, filter out entries that are not part of the
...@@ -360,10 +358,12 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -360,10 +358,12 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
#pragma mark UISearchBarDelegate #pragma mark UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar*)searchBar { - (void)searchBarTextDidBeginEditing:(UISearchBar*)searchBar {
self.searchInProgress = YES;
[self updateEntriesStatusMessage]; [self updateEntriesStatusMessage];
} }
- (void)searchBarTextDidEndEditing:(UISearchBar*)searchBar { - (void)searchBarTextDidEndEditing:(UISearchBar*)searchBar {
self.searchInProgress = NO;
[self updateEntriesStatusMessage]; [self updateEntriesStatusMessage];
} }
...@@ -439,7 +439,7 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -439,7 +439,7 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath];
// Only navigate and record metrics if a ItemTypeHistoryEntry was selected. // Only navigate and record metrics if a ItemTypeHistoryEntry was selected.
if (item.type == ItemTypeHistoryEntry) { if (item.type == ItemTypeHistoryEntry) {
if (self.searchController.isActive) { if (self.searchInProgress) {
// Set the searchController active property to NO or the SearchBar will // Set the searchController active property to NO or the SearchBar will
// cause the navigation controller to linger for a second when // cause the navigation controller to linger for a second when
// dismissing. // dismissing.
...@@ -542,8 +542,9 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -542,8 +542,9 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
- (void)fetchHistoryForQuery:(NSString*)query continuation:(BOOL)continuation { - (void)fetchHistoryForQuery:(NSString*)query continuation:(BOOL)continuation {
self.loading = YES; self.loading = YES;
// Add loading indicator if no items are shown. // Add loading indicator if no items are shown.
if (self.empty && !self.searchController.isActive) { if (self.empty && !self.searchInProgress) {
[self addLoadingIndicator]; [self startLoadingIndicatorWithLoadingMessage:l10n_util::GetNSString(
IDS_HISTORY_NO_RESULTS)];
} }
if (continuation) { if (continuation) {
...@@ -582,17 +583,14 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -582,17 +583,14 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
// section. // section.
- (void)updateEntriesStatusMessage { - (void)updateEntriesStatusMessage {
NSString* messageText = nil; NSString* messageText = nil;
TextItemColor messageColor;
if (self.empty) { if (self.empty) {
messageText = self.searchController.isActive messageText = self.searchInProgress
? l10n_util::GetNSString(IDS_HISTORY_NO_SEARCH_RESULTS) ? l10n_util::GetNSString(IDS_HISTORY_NO_SEARCH_RESULTS)
: l10n_util::GetNSString(IDS_HISTORY_NO_RESULTS); : nil;
messageColor = TextItemColorBlack;
} else if (self.shouldShowNoticeAboutOtherFormsOfBrowsingHistory && } else if (self.shouldShowNoticeAboutOtherFormsOfBrowsingHistory &&
!self.searchController.isActive) { !self.searchInProgress) {
messageText = messageText =
l10n_util::GetNSString(IDS_IOS_HISTORY_OTHER_FORMS_OF_HISTORY); l10n_util::GetNSString(IDS_IOS_HISTORY_OTHER_FORMS_OF_HISTORY);
messageColor = TextItemColorLightGrey;
} }
// Get the number of items currently at the StatusMessageSection. // Get the number of items currently at the StatusMessageSection.
...@@ -624,7 +622,6 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -624,7 +622,6 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
if ([messageText isEqualToString:oldEntriesStatusTextItem.text]) if ([messageText isEqualToString:oldEntriesStatusTextItem.text])
return; return;
oldEntriesStatusTextItem.text = messageText; oldEntriesStatusTextItem.text = messageText;
oldEntriesStatusTextItem.textColor = messageColor;
NSIndexPath* statusMessageIndexPath = [self.tableViewModel NSIndexPath* statusMessageIndexPath = [self.tableViewModel
indexPathForItemType:ItemTypeEntriesStatus indexPathForItemType:ItemTypeEntriesStatus
sectionIdentifier:kEntriesStatusSectionIdentifier]; sectionIdentifier:kEntriesStatusSectionIdentifier];
...@@ -635,7 +632,6 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -635,7 +632,6 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
TableViewTextItem* entriesStatusItem = TableViewTextItem* entriesStatusItem =
[[TableViewTextItem alloc] initWithType:ItemTypeEntriesStatus]; [[TableViewTextItem alloc] initWithType:ItemTypeEntriesStatus];
entriesStatusItem.text = messageText; entriesStatusItem.text = messageText;
entriesStatusItem.textColor = messageColor;
[self.tableViewModel addItem:entriesStatusItem [self.tableViewModel addItem:entriesStatusItem
toSectionWithIdentifier:kEntriesStatusSectionIdentifier]; toSectionWithIdentifier:kEntriesStatusSectionIdentifier];
NSIndexPath* statusMessageIndexPath = NSIndexPath* statusMessageIndexPath =
...@@ -697,12 +693,6 @@ const CGFloat kSeparationSpaceBetweenSections = 9; ...@@ -697,12 +693,6 @@ const CGFloat kSeparationSpaceBetweenSections = 9;
} }
} }
// Adds loading indicator to the top of the history tableView, if one is not
// already present.
- (void)addLoadingIndicator {
// TODO(crbug.com/805190): Migrate.
}
#pragma mark Navigation Toolbar Configuration #pragma mark Navigation Toolbar Configuration
// Animates the view configuration after flipping the current status of |[self // Animates the view configuration after flipping the current status of |[self
......
...@@ -429,6 +429,7 @@ id<GREYMatcher> ConfirmClearBrowsingDataButton() { ...@@ -429,6 +429,7 @@ id<GREYMatcher> ConfirmClearBrowsingDataButton() {
// Navigates to history and checks elements for accessibility. // Navigates to history and checks elements for accessibility.
- (void)testAccessibilityOnHistory { - (void)testAccessibilityOnHistory {
[self loadTestURLs];
[self openHistoryPanel]; [self openHistoryPanel];
chrome_test_util::VerifyAccessibilityForCurrentScreen(); chrome_test_util::VerifyAccessibilityForCurrentScreen();
// Close history. // Close history.
...@@ -461,6 +462,15 @@ id<GREYMatcher> ConfirmClearBrowsingDataButton() { ...@@ -461,6 +462,15 @@ id<GREYMatcher> ConfirmClearBrowsingDataButton() {
} }
- (void)assertNoHistoryShown { - (void)assertNoHistoryShown {
if (IsUIRefreshPhase1Enabled()) {
// TODO(crbug.com/838579): Add empty table matcher once its implemented.
id<GREYMatcher> historyEntryMatcher =
grey_allOf(grey_kindOfClass([TableViewURLCell class]),
grey_sufficientlyVisible(), nil);
[[EarlGrey selectElementWithMatcher:historyEntryMatcher]
assertWithMatcher:grey_nil()];
} else {
id<GREYMatcher> noHistoryMessageMatcher = id<GREYMatcher> noHistoryMessageMatcher =
grey_allOf(grey_text(l10n_util::GetNSString(IDS_HISTORY_NO_RESULTS)), grey_allOf(grey_text(l10n_util::GetNSString(IDS_HISTORY_NO_RESULTS)),
grey_sufficientlyVisible(), nil); grey_sufficientlyVisible(), nil);
...@@ -472,6 +482,7 @@ id<GREYMatcher> ConfirmClearBrowsingDataButton() { ...@@ -472,6 +482,7 @@ id<GREYMatcher> ConfirmClearBrowsingDataButton() {
grey_sufficientlyVisible(), nil); grey_sufficientlyVisible(), nil);
[[EarlGrey selectElementWithMatcher:historyEntryMatcher] [[EarlGrey selectElementWithMatcher:historyEntryMatcher]
assertWithMatcher:grey_nil()]; assertWithMatcher:grey_nil()];
}
} }
- (void)resetBrowsingDataPrefs { - (void)resetBrowsingDataPrefs {
......
...@@ -20,6 +20,7 @@ source_set("table_view") { ...@@ -20,6 +20,7 @@ source_set("table_view") {
deps = [ deps = [
":presentation", ":presentation",
":styler", ":styler",
":views",
"//base", "//base",
"//ios/chrome/browser/ui/list_model", "//ios/chrome/browser/ui/list_model",
"//ios/chrome/browser/ui/material_components", "//ios/chrome/browser/ui/material_components",
...@@ -59,6 +60,21 @@ source_set("presentation") { ...@@ -59,6 +60,21 @@ source_set("presentation") {
] ]
} }
source_set("views") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"table_view_loading_view.h",
"table_view_loading_view.mm",
]
deps = [
"//base",
"//ios/chrome/browser/ui",
"//ios/chrome/browser/ui/colors",
"//ios/chrome/browser/ui/material_components",
"//ios/third_party/material_components_ios",
]
}
source_set("unit_tests") { source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
testonly = true testonly = true
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#include "base/ios/block_types.h"
#import "ios/chrome/browser/ui/material_components/app_bar_presenting.h" #import "ios/chrome/browser/ui/material_components/app_bar_presenting.h"
#import "ios/chrome/browser/ui/table_view/chrome_table_view_consumer.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_consumer.h"
#import "ios/chrome/browser/ui/table_view/table_view_model.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h"
...@@ -49,6 +50,14 @@ typedef NS_ENUM(NSInteger, ChromeTableViewControllerStyle) { ...@@ -49,6 +50,14 @@ typedef NS_ENUM(NSInteger, ChromeTableViewControllerStyle) {
// override this method in order to get a clean tableViewModel. // override this method in order to get a clean tableViewModel.
- (void)loadModel NS_REQUIRES_SUPER; - (void)loadModel NS_REQUIRES_SUPER;
// Adds and starts a loading indicator in the center of the
// ChromeTableViewController, if one is not already present. This will remove
// any existing table view background views.
- (void)startLoadingIndicatorWithLoadingMessage:(NSString*)loadingMessage;
// Removes and stops the loading indicator, if one is present.
- (void)stopLoadingIndicatorWithCompletion:(ProceduralBlock)completion;
// Methods for reconfiguring and reloading the table view are provided by // Methods for reconfiguring and reloading the table view are provided by
// ChromeTableViewConsumer. // ChromeTableViewConsumer.
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
#import "ios/chrome/browser/ui/table_view/table_view_loading_view.h"
#import "ios/chrome/browser/ui/table_view/table_view_model.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h"
#import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h" #import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h"
...@@ -16,8 +17,15 @@ ...@@ -16,8 +17,15 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
@interface ChromeTableViewController ()
// The loading view that will be displayed for [self
// startLoadingIndicatorWithLoadingMessage].
@property(nonatomic, strong) TableViewLoadingView* loadingView;
@end
@implementation ChromeTableViewController @implementation ChromeTableViewController
@synthesize appBar = _appBar; @synthesize appBar = _appBar;
@synthesize loadingView = _loadingView;
@synthesize styler = _styler; @synthesize styler = _styler;
@synthesize tableViewModel = _tableViewModel; @synthesize tableViewModel = _tableViewModel;
...@@ -63,8 +71,6 @@ ...@@ -63,8 +71,6 @@
} }
} }
#pragma mark - ViewLifeCycle
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
...@@ -82,6 +88,29 @@ ...@@ -82,6 +88,29 @@
} }
} }
- (void)startLoadingIndicatorWithLoadingMessage:(NSString*)loadingMessage {
if (!self.loadingView) {
TableViewLoadingView* waitingView =
[[TableViewLoadingView alloc] initWithFrame:self.view.bounds
loadingMessage:loadingMessage];
self.loadingView = waitingView;
self.tableView.backgroundView = self.loadingView;
[self.loadingView startLoadingIndicator];
}
}
- (void)stopLoadingIndicatorWithCompletion:(ProceduralBlock)completion {
if (self.loadingView) {
[self.loadingView stopLoadingIndicatorWithCompletion:^{
if (completion)
completion();
[self.loadingView removeFromSuperview];
self.tableView.backgroundView = nil;
self.loadingView = nil;
}];
}
}
#pragma mark - UITableViewDataSource #pragma mark - UITableViewDataSource
- (UITableViewCell*)tableView:(UITableView*)tableView - (UITableViewCell*)tableView:(UITableView*)tableView
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_LOADING_VIEW_H_
#define IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_LOADING_VIEW_H_
#import <UIKit/UIKit.h>
#include "base/ios/block_types.h"
// Displays an activity indicator with an optional message over a
// clearBackground.
@interface TableViewLoadingView : UIView
- (instancetype)initWithFrame:(CGRect)frame
loadingMessage:(NSString*)message NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
// Call this method when this view is added to the visible view hierarchy.
// An activity indicator will be presented if this view is still in the view
// hierarchy at that time.
- (void)startLoadingIndicator;
// Call this method when this view is removed from the visible view hierarchy.
// |completion| will be called when this view is done animating out, and can be
// nil.
- (void)stopLoadingIndicatorWithCompletion:(ProceduralBlock)completion;
@end
#endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_LOADING_VIEW_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/table_view/table_view_loading_view.h"
#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
#import "ios/chrome/browser/ui/material_components/activity_indicator.h"
#import "ios/chrome/browser/ui/rtl_geometry.h"
#import "ios/third_party/material_components_ios/src/components/ActivityIndicator/src/MaterialActivityIndicator.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// The MDCActivityIndicator radius.
const float kLoadingIndicatorRadius = 9.0;
// The StackView width.
const float kStackViewWidth = 227.0;
// The StackView vertical spacing.
const float kStackViewVerticalSpacing = 30.0;
}
@interface TableViewLoadingView ()<MDCActivityIndicatorDelegate>
// MDCActivityIndicator that will be displayed.
@property(nonatomic, retain) MDCActivityIndicator* activityIndicator;
// Completion block ran after |self.activityIndicator| stops.
@property(nonatomic, copy) ProceduralBlock animateOutCompletionBlock;
// Message being displayed along the activity indicator.
@property(nonatomic, copy) NSString* loadingMessage;
@end
@implementation TableViewLoadingView
@synthesize activityIndicator = _activityIndicator;
@synthesize animateOutCompletionBlock = _animateOutCompletionBlock;
@synthesize loadingMessage = _loadingMessage;
#pragma mark - Public Interface
- (instancetype)initWithFrame:(CGRect)frame {
return [self initWithFrame:frame loadingMessage:nil];
}
- (instancetype)initWithFrame:(CGRect)frame loadingMessage:(NSString*)message {
self = [super initWithFrame:frame];
if (self) {
self.loadingMessage = message;
}
return self;
}
- (void)startLoadingIndicator {
self.activityIndicator =
[[MDCActivityIndicator alloc] initWithFrame:CGRectZero];
self.activityIndicator.radius = kLoadingIndicatorRadius;
self.activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
self.activityIndicator.cycleColors =
@[ [[MDCPalette cr_bluePalette] tint500] ];
self.activityIndicator.delegate = self;
UILabel* messageLabel = [[UILabel alloc] init];
messageLabel.text = self.loadingMessage;
messageLabel.numberOfLines = 0;
messageLabel.lineBreakMode = NSLineBreakByWordWrapping;
messageLabel.textAlignment = NSTextAlignmentCenter;
messageLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
messageLabel.textColor = [UIColor grayColor];
// Vertical stack view that holds the activity indicator and message.
UIStackView* verticalStack = [[UIStackView alloc]
initWithArrangedSubviews:@[ self.activityIndicator, messageLabel ]];
verticalStack.axis = UILayoutConstraintAxisVertical;
verticalStack.spacing = kStackViewVerticalSpacing;
verticalStack.distribution = UIStackViewDistributionFill;
verticalStack.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:verticalStack];
[NSLayoutConstraint activateConstraints:@[
[verticalStack.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
[verticalStack.centerXAnchor constraintEqualToAnchor:self.centerXAnchor],
[verticalStack.widthAnchor constraintEqualToConstant:kStackViewWidth]
]];
[self.activityIndicator startAnimating];
}
- (void)stopLoadingIndicatorWithCompletion:(ProceduralBlock)completion {
if (self.activityIndicator) {
self.animateOutCompletionBlock = completion;
[self.activityIndicator stopAnimating];
} else if (completion) {
completion();
}
}
#pragma mark - MDCActivityIndicatorDelegate
- (void)activityIndicatorAnimationDidFinish:
(MDCActivityIndicator*)activityIndicator {
[self.activityIndicator removeFromSuperview];
self.activityIndicator = nil;
if (self.animateOutCompletionBlock)
self.animateOutCompletionBlock();
self.animateOutCompletionBlock = nil;
}
@end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment