OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/chrome/browser/ui/settings/sync_encryption_passphrase_collection_vi ew_controller.h" | 5 #import "ios/chrome/browser/ui/settings/sync_encryption_passphrase_collection_vi ew_controller.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/i18n/time_formatting.h" | 9 #include "base/i18n/time_formatting.h" |
10 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
11 #import "base/mac/objc_property_releaser.h" | 11 |
12 #import "base/mac/scoped_nsobject.h" | |
13 #include "base/strings/sys_string_conversions.h" | 12 #include "base/strings/sys_string_conversions.h" |
14 #include "components/browser_sync/profile_sync_service.h" | 13 #include "components/browser_sync/profile_sync_service.h" |
15 #include "components/google/core/browser/google_util.h" | 14 #include "components/google/core/browser/google_util.h" |
16 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 15 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
17 #import "components/signin/ios/browser/oauth2_token_service_observer_bridge.h" | 16 #import "components/signin/ios/browser/oauth2_token_service_observer_bridge.h" |
18 #include "components/strings/grit/components_strings.h" | 17 #include "components/strings/grit/components_strings.h" |
19 #include "ios/chrome/browser/application_context.h" | 18 #include "ios/chrome/browser/application_context.h" |
20 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" | 19 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
21 #include "ios/chrome/browser/chrome_url_constants.h" | 20 #include "ios/chrome/browser/chrome_url_constants.h" |
22 #import "ios/chrome/browser/signin/authentication_service.h" | 21 #import "ios/chrome/browser/signin/authentication_service.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
38 #import "ios/chrome/browser/ui/sync/sync_util.h" | 37 #import "ios/chrome/browser/ui/sync/sync_util.h" |
39 #import "ios/chrome/browser/ui/uikit_ui_util.h" | 38 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
40 #include "ios/chrome/grit/ios_strings.h" | 39 #include "ios/chrome/grit/ios_strings.h" |
41 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" | 40 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" |
42 #import "ios/third_party/material_components_ios/src/components/Typography/src/M aterialTypography.h" | 41 #import "ios/third_party/material_components_ios/src/components/Typography/src/M aterialTypography.h" |
43 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoF ontLoader.h" | 42 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoF ontLoader.h" |
44 #include "ui/base/l10n/l10n_util.h" | 43 #include "ui/base/l10n/l10n_util.h" |
45 #include "ui/base/l10n/l10n_util_mac.h" | 44 #include "ui/base/l10n/l10n_util_mac.h" |
46 #include "url/gurl.h" | 45 #include "url/gurl.h" |
47 | 46 |
47 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
48 #error "This file requires ARC support." | |
49 #endif | |
50 | |
48 using namespace ios_internal::sync_encryption_passphrase; | 51 using namespace ios_internal::sync_encryption_passphrase; |
49 | 52 |
50 namespace { | 53 namespace { |
51 | 54 |
52 const CGFloat kSpinnerButtonCustomViewSize = 48; | 55 const CGFloat kSpinnerButtonCustomViewSize = 48; |
53 const CGFloat kSpinnerButtonPadding = 18; | 56 const CGFloat kSpinnerButtonPadding = 18; |
54 | 57 |
55 } // namespace | 58 } // namespace |
56 | 59 |
57 @interface SyncEncryptionPassphraseCollectionViewController ()< | 60 @interface SyncEncryptionPassphraseCollectionViewController ()< |
58 OAuth2TokenServiceObserverBridgeDelegate, | 61 OAuth2TokenServiceObserverBridgeDelegate, |
59 SettingsControllerProtocol> { | 62 SettingsControllerProtocol> { |
60 ios::ChromeBrowserState* browserState_; | 63 ios::ChromeBrowserState* browserState_; |
61 // Whether the decryption progress is currently being shown. | 64 // Whether the decryption progress is currently being shown. |
62 BOOL isDecryptionProgressShown_; | 65 BOOL isDecryptionProgressShown_; |
63 base::scoped_nsobject<NSString> savedTitle_; | 66 NSString* savedTitle_; |
64 base::scoped_nsobject<UIBarButtonItem> savedLeftButton_; | 67 UIBarButtonItem* savedLeftButton_; |
65 std::unique_ptr<SyncObserverBridge> syncObserver_; | 68 std::unique_ptr<SyncObserverBridge> syncObserver_; |
66 std::unique_ptr<OAuth2TokenServiceObserverBridge> tokenServiceObserver_; | 69 std::unique_ptr<OAuth2TokenServiceObserverBridge> tokenServiceObserver_; |
67 base::scoped_nsobject<UITextField> passphrase_; | 70 UITextField* passphrase_; |
68 base::mac::ObjCPropertyReleaser | |
69 propertyReleaser_SyncEncryptionPassphraseCollectionViewController_; | |
70 } | 71 } |
71 | 72 |
72 // Sets up the navigation bar's right button. The button will be enabled iff | 73 // Sets up the navigation bar's right button. The button will be enabled iff |
73 // |-areAllFieldsFilled| returns YES. | 74 // |-areAllFieldsFilled| returns YES. |
74 - (void)setRightNavBarItem; | 75 - (void)setRightNavBarItem; |
75 | 76 |
76 // Returns a passphrase message item. | 77 // Returns a passphrase message item. |
77 - (CollectionViewItem*)passphraseMessageItem; | 78 - (CollectionViewItem*)passphraseMessageItem; |
78 | 79 |
79 // Returns a passphrase item. | 80 // Returns a passphrase item. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
129 } else { | 130 } else { |
130 self.headerMessage = l10n_util::GetNSStringF( | 131 self.headerMessage = l10n_util::GetNSStringF( |
131 IDS_IOS_SYNC_ENTER_PASSPHRASE_BODY_WITH_EMAIL, | 132 IDS_IOS_SYNC_ENTER_PASSPHRASE_BODY_WITH_EMAIL, |
132 base::SysNSStringToUTF16(userEmail)); | 133 base::SysNSStringToUTF16(userEmail)); |
133 } | 134 } |
134 } else { | 135 } else { |
135 self.headerMessage = | 136 self.headerMessage = |
136 l10n_util::GetNSString(IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY); | 137 l10n_util::GetNSString(IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY); |
137 } | 138 } |
138 self.processingMessage = l10n_util::GetNSString(IDS_SYNC_LOGIN_SETTING_UP); | 139 self.processingMessage = l10n_util::GetNSString(IDS_SYNC_LOGIN_SETTING_UP); |
139 footerMessage_ = | 140 footerMessage_ = l10n_util::GetNSString(IDS_IOS_SYNC_PASSPHRASE_RECOVER); |
140 [l10n_util::GetNSString(IDS_IOS_SYNC_PASSPHRASE_RECOVER) retain]; | |
141 | 141 |
142 tokenServiceObserver_.reset(new OAuth2TokenServiceObserverBridge( | 142 tokenServiceObserver_.reset(new OAuth2TokenServiceObserverBridge( |
143 OAuth2TokenServiceFactory::GetForBrowserState(browserState_), self)); | 143 OAuth2TokenServiceFactory::GetForBrowserState(browserState_), self)); |
144 | 144 |
145 propertyReleaser_SyncEncryptionPassphraseCollectionViewController_.Init( | |
146 self, [SyncEncryptionPassphraseCollectionViewController class]); | |
147 | |
148 [self loadModel]; | 145 [self loadModel]; |
149 } | 146 } |
150 return self; | 147 return self; |
151 } | 148 } |
152 | 149 |
153 - (UITextField*)passphrase { | 150 - (UITextField*)passphrase { |
154 return passphrase_; | 151 return passphrase_; |
155 } | 152 } |
156 | 153 |
157 - (NSString*)syncErrorMessage { | 154 - (NSString*)syncErrorMessage { |
(...skipping 15 matching lines...) Expand all Loading... | |
173 #pragma mark - View lifecycle | 170 #pragma mark - View lifecycle |
174 | 171 |
175 - (void)viewDidLoad { | 172 - (void)viewDidLoad { |
176 [super viewDidLoad]; | 173 [super viewDidLoad]; |
177 [self setRightNavBarItem]; | 174 [self setRightNavBarItem]; |
178 } | 175 } |
179 | 176 |
180 - (void)didReceiveMemoryWarning { | 177 - (void)didReceiveMemoryWarning { |
181 [super didReceiveMemoryWarning]; | 178 [super didReceiveMemoryWarning]; |
182 if (![self isViewLoaded]) { | 179 if (![self isViewLoaded]) { |
183 passphrase_.reset(); | 180 passphrase_ = nil; |
184 } | 181 } |
185 } | 182 } |
186 | 183 |
187 - (void)viewWillDisappear:(BOOL)animated { | 184 - (void)viewWillDisappear:(BOOL)animated { |
188 [super viewWillDisappear:animated]; | 185 [super viewWillDisappear:animated]; |
189 [self.passphrase resignFirstResponder]; | 186 [self.passphrase resignFirstResponder]; |
190 } | 187 } |
191 | 188 |
192 - (void)viewDidDisappear:(BOOL)animated { | 189 - (void)viewDidDisappear:(BOOL)animated { |
193 [super viewDidDisappear:animated]; | 190 [super viewDidDisappear:animated]; |
(...skipping 25 matching lines...) Expand all Loading... | |
219 // section, to work around a drawing bug in MDC. | 216 // section, to work around a drawing bug in MDC. |
220 [model addSectionWithIdentifier:SectionIdentifierFooter]; | 217 [model addSectionWithIdentifier:SectionIdentifierFooter]; |
221 [model addItem:[self footerItem] | 218 [model addItem:[self footerItem] |
222 toSectionWithIdentifier:SectionIdentifierFooter]; | 219 toSectionWithIdentifier:SectionIdentifierFooter]; |
223 } | 220 } |
224 | 221 |
225 #pragma mark - Items | 222 #pragma mark - Items |
226 | 223 |
227 - (CollectionViewItem*)passphraseMessageItem { | 224 - (CollectionViewItem*)passphraseMessageItem { |
228 CardMultilineItem* item = | 225 CardMultilineItem* item = |
229 [[[CardMultilineItem alloc] initWithType:ItemTypeMessage] autorelease]; | 226 [[CardMultilineItem alloc] initWithType:ItemTypeMessage]; |
230 item.text = headerMessage_; | 227 item.text = headerMessage_; |
231 return item; | 228 return item; |
232 } | 229 } |
233 | 230 |
234 - (CollectionViewItem*)passphraseItem { | 231 - (CollectionViewItem*)passphraseItem { |
235 if (passphrase_) { | 232 if (passphrase_) { |
236 [self unregisterTextField:passphrase_]; | 233 [self unregisterTextField:passphrase_]; |
237 } | 234 } |
238 passphrase_.reset([[UITextField alloc] init]); | 235 passphrase_ = [[UITextField alloc] init]; |
239 [passphrase_ setFont:[MDCTypography body1Font]]; | 236 [passphrase_ setFont:[MDCTypography body1Font]]; |
240 [passphrase_ setSecureTextEntry:YES]; | 237 [passphrase_ setSecureTextEntry:YES]; |
241 [passphrase_ setBackgroundColor:[UIColor clearColor]]; | 238 [passphrase_ setBackgroundColor:[UIColor clearColor]]; |
242 [passphrase_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; | 239 [passphrase_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; |
243 [passphrase_ setAutocorrectionType:UITextAutocorrectionTypeNo]; | 240 [passphrase_ setAutocorrectionType:UITextAutocorrectionTypeNo]; |
244 [passphrase_ | 241 [passphrase_ |
245 setPlaceholder:l10n_util::GetNSString(IDS_SYNC_PASSPHRASE_LABEL)]; | 242 setPlaceholder:l10n_util::GetNSString(IDS_SYNC_PASSPHRASE_LABEL)]; |
246 [self registerTextField:passphrase_]; | 243 [self registerTextField:passphrase_]; |
247 | 244 |
248 BYOTextFieldItem* item = [[[BYOTextFieldItem alloc] | 245 BYOTextFieldItem* item = |
249 initWithType:ItemTypeEnterPassphrase] autorelease]; | 246 [[BYOTextFieldItem alloc] initWithType:ItemTypeEnterPassphrase]; |
250 item.textField = passphrase_; | 247 item.textField = passphrase_; |
251 return item; | 248 return item; |
252 } | 249 } |
253 | 250 |
254 - (CollectionViewItem*)passphraseErrorItemWithMessage:(NSString*)errorMessage { | 251 - (CollectionViewItem*)passphraseErrorItemWithMessage:(NSString*)errorMessage { |
255 PassphraseErrorItem* item = | 252 PassphraseErrorItem* item = |
256 [[[PassphraseErrorItem alloc] initWithType:ItemTypeError] autorelease]; | 253 [[PassphraseErrorItem alloc] initWithType:ItemTypeError]; |
257 item.text = errorMessage; | 254 item.text = errorMessage; |
258 return item; | 255 return item; |
259 } | 256 } |
260 | 257 |
261 - (CollectionViewItem*)footerItem { | 258 - (CollectionViewItem*)footerItem { |
262 CollectionViewFooterItem* footerItem = [[[CollectionViewFooterItem alloc] | 259 CollectionViewFooterItem* footerItem = |
263 initWithType:ItemTypeFooter] autorelease]; | 260 [[CollectionViewFooterItem alloc] initWithType:ItemTypeFooter]; |
264 footerItem.text = self.footerMessage; | 261 footerItem.text = self.footerMessage; |
265 footerItem.linkURL = google_util::AppendGoogleLocaleParam( | 262 footerItem.linkURL = google_util::AppendGoogleLocaleParam( |
266 GURL(kSyncGoogleDashboardURL), | 263 GURL(kSyncGoogleDashboardURL), |
267 GetApplicationContext()->GetApplicationLocale()); | 264 GetApplicationContext()->GetApplicationLocale()); |
268 footerItem.linkDelegate = self; | 265 footerItem.linkDelegate = self; |
269 return footerItem; | 266 return footerItem; |
270 } | 267 } |
271 | 268 |
272 #pragma mark - MDCCollectionViewStylingDelegate | 269 #pragma mark - MDCCollectionViewStylingDelegate |
273 | 270 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 service->EnableEncryptEverything(); | 380 service->EnableEncryptEverything(); |
384 service->SetEncryptionPassphrase( | 381 service->SetEncryptionPassphrase( |
385 passphrase, browser_sync::ProfileSyncService::EXPLICIT); | 382 passphrase, browser_sync::ProfileSyncService::EXPLICIT); |
386 } | 383 } |
387 [self reloadData]; | 384 [self reloadData]; |
388 } | 385 } |
389 | 386 |
390 - (void)setRightNavBarItem { | 387 - (void)setRightNavBarItem { |
391 UIBarButtonItem* submitButtonItem = self.navigationItem.rightBarButtonItem; | 388 UIBarButtonItem* submitButtonItem = self.navigationItem.rightBarButtonItem; |
392 if (!submitButtonItem) { | 389 if (!submitButtonItem) { |
393 submitButtonItem = [[[UIBarButtonItem alloc] | 390 submitButtonItem = [[UIBarButtonItem alloc] |
394 initWithTitle:l10n_util::GetNSString(IDS_IOS_SYNC_DECRYPT_BUTTON) | 391 initWithTitle:l10n_util::GetNSString(IDS_IOS_SYNC_DECRYPT_BUTTON) |
395 style:UIBarButtonItemStylePlain | 392 style:UIBarButtonItemStylePlain |
396 target:self | 393 target:self |
397 action:@selector(signInPressed)] autorelease]; | 394 action:@selector(signInPressed)]; |
398 } | 395 } |
399 submitButtonItem.enabled = [self areAllFieldsFilled]; | 396 submitButtonItem.enabled = [self areAllFieldsFilled]; |
400 | 397 |
401 // Only setting the enabled state doesn't make the item redraw. As a | 398 // Only setting the enabled state doesn't make the item redraw. As a |
402 // workaround, set it again. | 399 // workaround, set it again. |
403 self.navigationItem.rightBarButtonItem = submitButtonItem; | 400 self.navigationItem.rightBarButtonItem = submitButtonItem; |
404 } | 401 } |
405 | 402 |
406 - (BOOL)areAllFieldsFilled { | 403 - (BOOL)areAllFieldsFilled { |
407 return [self.passphrase text].length > 0; | 404 return [self.passphrase text].length > 0; |
408 } | 405 } |
409 | 406 |
410 - (void)clearFieldsOnError:(NSString*)errorMessage { | 407 - (void)clearFieldsOnError:(NSString*)errorMessage { |
411 self.syncErrorMessage = errorMessage; | 408 self.syncErrorMessage = errorMessage; |
412 [self.passphrase setText:@""]; | 409 [self.passphrase setText:@""]; |
413 } | 410 } |
414 | 411 |
415 - (void)showDecryptionProgress { | 412 - (void)showDecryptionProgress { |
416 if (isDecryptionProgressShown_) | 413 if (isDecryptionProgressShown_) |
417 return; | 414 return; |
418 isDecryptionProgressShown_ = YES; | 415 isDecryptionProgressShown_ = YES; |
419 | 416 |
420 // Hide the button. | 417 // Hide the button. |
421 self.navigationItem.rightBarButtonItem = nil; | 418 self.navigationItem.rightBarButtonItem = nil; |
422 | 419 |
423 // Custom title view with spinner. | 420 // Custom title view with spinner. |
424 DCHECK(!savedTitle_); | 421 DCHECK(!savedTitle_); |
425 DCHECK(!savedLeftButton_); | 422 DCHECK(!savedLeftButton_); |
426 savedLeftButton_.reset([self.navigationItem.leftBarButtonItem retain]); | 423 savedLeftButton_ = self.navigationItem.leftBarButtonItem; |
427 self.navigationItem.leftBarButtonItem = [self spinnerButton]; | 424 self.navigationItem.leftBarButtonItem = [self spinnerButton]; |
428 savedTitle_.reset([self.title copy]); | 425 savedTitle_ = [self.title copy]; |
429 self.title = processingMessage_; | 426 self.title = processingMessage_; |
430 } | 427 } |
431 | 428 |
432 - (void)hideDecryptionProgress { | 429 - (void)hideDecryptionProgress { |
433 if (!isDecryptionProgressShown_) | 430 if (!isDecryptionProgressShown_) |
434 return; | 431 return; |
435 isDecryptionProgressShown_ = NO; | 432 isDecryptionProgressShown_ = NO; |
436 | 433 |
437 self.navigationItem.leftBarButtonItem = savedLeftButton_.autorelease(); | 434 self.navigationItem.leftBarButtonItem = savedLeftButton_ = nil; |
lpromero
2017/06/15 08:31:49
Wow. That's a bad one (idem below). We should make
| |
438 self.title = savedTitle_.autorelease(); | 435 self.title = savedTitle_ = nil; |
439 [self setRightNavBarItem]; | 436 [self setRightNavBarItem]; |
440 } | 437 } |
441 | 438 |
442 - (void)registerTextField:(UITextField*)textField { | 439 - (void)registerTextField:(UITextField*)textField { |
443 [textField addTarget:self | 440 [textField addTarget:self |
444 action:@selector(textFieldDidBeginEditing:) | 441 action:@selector(textFieldDidBeginEditing:) |
445 forControlEvents:UIControlEventEditingDidBegin]; | 442 forControlEvents:UIControlEventEditingDidBegin]; |
446 [textField addTarget:self | 443 [textField addTarget:self |
447 action:@selector(textFieldDidChange:) | 444 action:@selector(textFieldDidChange:) |
448 forControlEvents:UIControlEventEditingChanged]; | 445 forControlEvents:UIControlEventEditingChanged]; |
(...skipping 10 matching lines...) Expand all Loading... | |
459 action:@selector(textFieldDidChange:) | 456 action:@selector(textFieldDidChange:) |
460 forControlEvents:UIControlEventEditingChanged]; | 457 forControlEvents:UIControlEventEditingChanged]; |
461 [textField removeTarget:self | 458 [textField removeTarget:self |
462 action:@selector(textFieldDidEndEditing:) | 459 action:@selector(textFieldDidEndEditing:) |
463 forControlEvents:UIControlEventEditingDidEndOnExit]; | 460 forControlEvents:UIControlEventEditingDidEndOnExit]; |
464 } | 461 } |
465 | 462 |
466 - (UIBarButtonItem*)spinnerButton { | 463 - (UIBarButtonItem*)spinnerButton { |
467 CGRect customViewFrame = CGRectMake(0, 0, kSpinnerButtonCustomViewSize, | 464 CGRect customViewFrame = CGRectMake(0, 0, kSpinnerButtonCustomViewSize, |
468 kSpinnerButtonCustomViewSize); | 465 kSpinnerButtonCustomViewSize); |
469 base::scoped_nsobject<UIView> customView( | 466 UIView* customView = [[UIView alloc] initWithFrame:customViewFrame]; |
470 [[UIView alloc] initWithFrame:customViewFrame]); | |
471 | 467 |
472 base::scoped_nsobject<UIActivityIndicatorView> spinner( | 468 UIActivityIndicatorView* spinner = [[UIActivityIndicatorView alloc] |
473 [[UIActivityIndicatorView alloc] | 469 initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; |
474 initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]); | |
475 | 470 |
476 CGRect spinnerFrame = [spinner bounds]; | 471 CGRect spinnerFrame = [spinner bounds]; |
477 spinnerFrame.origin.x = kSpinnerButtonPadding; | 472 spinnerFrame.origin.x = kSpinnerButtonPadding; |
478 spinnerFrame.origin.y = kSpinnerButtonPadding; | 473 spinnerFrame.origin.y = kSpinnerButtonPadding; |
479 [spinner setFrame:spinnerFrame]; | 474 [spinner setFrame:spinnerFrame]; |
480 [customView addSubview:spinner]; | 475 [customView addSubview:spinner]; |
481 | 476 |
482 base::scoped_nsobject<UIBarButtonItem> leftBarButtonItem( | 477 UIBarButtonItem* leftBarButtonItem = |
483 [[UIBarButtonItem alloc] initWithCustomView:customView]); | 478 [[UIBarButtonItem alloc] initWithCustomView:customView]; |
484 | 479 |
485 [spinner setHidesWhenStopped:NO]; | 480 [spinner setHidesWhenStopped:NO]; |
486 [spinner startAnimating]; | 481 [spinner startAnimating]; |
487 | 482 |
488 return leftBarButtonItem.autorelease(); | 483 return leftBarButtonItem = nil; |
489 } | 484 } |
490 | 485 |
491 - (void)stopObserving { | 486 - (void)stopObserving { |
492 // Stops observing the sync service. This is required during the shutdown | 487 // Stops observing the sync service. This is required during the shutdown |
493 // phase to avoid observing sync events for a browser state that is being | 488 // phase to avoid observing sync events for a browser state that is being |
494 // killed. | 489 // killed. |
495 syncObserver_.reset(); | 490 syncObserver_.reset(); |
496 tokenServiceObserver_.reset(); | 491 tokenServiceObserver_.reset(); |
497 } | 492 } |
498 | 493 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
571 self.navigationController) popViewControllerOrCloseSettingsAnimated:NO]; | 566 self.navigationController) popViewControllerOrCloseSettingsAnimated:NO]; |
572 } | 567 } |
573 | 568 |
574 #pragma mark - SettingsControllerProtocol callbacks | 569 #pragma mark - SettingsControllerProtocol callbacks |
575 | 570 |
576 - (void)settingsWillBeDismissed { | 571 - (void)settingsWillBeDismissed { |
577 [self stopObserving]; | 572 [self stopObserving]; |
578 } | 573 } |
579 | 574 |
580 @end | 575 @end |
OLD | NEW |