diff --git a/MasterPassword/ObjC/iOS/MPCoachmarkViewController.h b/MasterPassword/ObjC/iOS/MPCoachmarkViewController.h index 7ec95b51..98e63497 100644 --- a/MasterPassword/ObjC/iOS/MPCoachmarkViewController.h +++ b/MasterPassword/ObjC/iOS/MPCoachmarkViewController.h @@ -31,6 +31,17 @@ @interface MPCoachmarkViewController : UIViewController @property(nonatomic, strong) MPCoachmark *coachmark; +@property(nonatomic, strong) IBOutlet UIView *view0; +@property(nonatomic, strong) IBOutlet UIView *view1; +@property(nonatomic, strong) IBOutlet UIView *view2; +@property(nonatomic, strong) IBOutlet UIView *view3; +@property(nonatomic, strong) IBOutlet UIView *view4; +@property(nonatomic, strong) IBOutlet UIView *view5; +@property(nonatomic, strong) IBOutlet UIView *view6; +@property(nonatomic, strong) IBOutlet UIView *view7; +@property(nonatomic, strong) IBOutlet UIView *view8; +@property(nonatomic, strong) IBOutlet UIView *view9; +@property(nonatomic, strong) IBOutlet UIProgressView *viewProgress; - (IBAction)close:(id)sender; diff --git a/MasterPassword/ObjC/iOS/MPCoachmarkViewController.m b/MasterPassword/ObjC/iOS/MPCoachmarkViewController.m index d7f8af7f..40c4ec87 100644 --- a/MasterPassword/ObjC/iOS/MPCoachmarkViewController.m +++ b/MasterPassword/ObjC/iOS/MPCoachmarkViewController.m @@ -1,12 +1,12 @@ /** - * Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com) - * - * See the enclosed file LICENSE for license information (LGPLv3). If you did - * not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt - * - * @author Maarten Billemont - * @license http://www.gnu.org/licenses/lgpl-3.0.txt - */ +* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com) +* +* See the enclosed file LICENSE for license information (LGPLv3). If you did +* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt +* +* @author Maarten Billemont +* @license http://www.gnu.org/licenses/lgpl-3.0.txt +*/ // // MPCoachmarkViewController.h @@ -19,6 +19,56 @@ #import "MPCoachmarkViewController.h" @implementation MPCoachmarkViewController { + NSArray *_views; + NSUInteger _nextView; + __weak NSTimer *_viewTimer; +} + +- (void)viewDidLoad { + + [super viewDidLoad]; + + _views = [NSArray arrayWithObjects: + self.view0, self.view1, self.view2, self.view3, self.view4, self.view5, self.view6, self.view7, self.view8, self.view9, nil]; +} + +- (void)viewWillAppear:(BOOL)animated { + + [super viewWillAppear:animated]; + + self.viewProgress.hidden = NO; + self.viewProgress.progress = 0; + [_views makeObjectsPerformSelector:@selector( setAlpha: ) withObject:@0]; + _nextView = 0; +} + +- (void)viewDidAppear:(BOOL)animated { + + [super viewDidAppear:animated]; + + [UIView animateWithDuration:0.3f animations:^{ + [_views[_nextView++] setAlpha:1]; + }]; + + _viewTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 block:^(NSTimer *timer) { + self.viewProgress.progress += 1.0f / 50; + + if (self.viewProgress.progress == 1) + [UIView animateWithDuration:0.3f animations:^{ + self.viewProgress.progress = 0; + [_views[_nextView++] setAlpha:1]; + + if (_nextView >= [_views count]) { + [_viewTimer invalidate]; + self.viewProgress.hidden = YES; + } + }]; + } repeats:YES]; +} + +- (UIStatusBarStyle)preferredStatusBarStyle { + + return UIStatusBarStyleLightContent; } - (IBAction)close:(id)sender { @@ -33,6 +83,7 @@ @implementation MPCoachmark + (instancetype)coachmarkForClass:(Class)coachedClass version:(NSInteger)coachedVersion { + MPCoachmark *coachmark = [self new]; coachmark.coachedClass = coachedClass; coachmark.coachedVersion = coachedVersion; diff --git a/MasterPassword/ObjC/iOS/MPPasswordLargeCell.h b/MasterPassword/ObjC/iOS/MPPasswordLargeCell.h index 782b01b2..c3bae0e8 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordLargeCell.h +++ b/MasterPassword/ObjC/iOS/MPPasswordLargeCell.h @@ -38,8 +38,9 @@ typedef NS_ENUM (NSUInteger, MPContentFieldMode) { + (instancetype)dequeueCellWithType:(MPElementType)type fromCollectionView:(UICollectionView *)collectionView atIndexPath:(NSIndexPath *)indexPath; -- (void)reloadWithElement:(MPElementEntity *)mainElement; -- (void)reloadWithTransientSite:(NSString *)siteName; +- (void)update; +- (void)updateWithElement:(MPElementEntity *)mainElement; +- (void)updateWithTransientSite:(NSString *)siteName; - (void)resolveContentOfCellTypeForTransientSite:(NSString *)siteName usingKey:(MPKey *)key result:(void (^)(NSString *))resultBlock; - (void)resolveContentOfCellTypeForElement:(MPElementEntity *)element usingKey:(MPKey *)key result:(void (^)(NSString *))resultBlock; diff --git a/MasterPassword/ObjC/iOS/MPPasswordLargeCell.m b/MasterPassword/ObjC/iOS/MPPasswordLargeCell.m index cd106de7..0f9cedb3 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordLargeCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordLargeCell.m @@ -1,12 +1,12 @@ /** - * Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com) - * - * See the enclosed file LICENSE for license information (LGPLv3). If you did - * not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt - * - * @author Maarten Billemont - * @license http://www.gnu.org/licenses/lgpl-3.0.txt - */ +* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com) +* +* See the enclosed file LICENSE for license information (LGPLv3). If you did +* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt +* +* @author Maarten Billemont +* @license http://www.gnu.org/licenses/lgpl-3.0.txt +*/ // // MPAvatarCell.h @@ -22,7 +22,6 @@ #import "MPPasswordLargeGeneratedCell.h" #import "MPPasswordLargeStoredCell.h" #import "MPPasswordTypesCell.h" -#import "MPPasswordLargeDeleteCell.h" @implementation MPPasswordLargeCell @@ -32,14 +31,12 @@ atIndexPath:(NSIndexPath *)indexPath { NSString *reuseIdentifier; - if (indexPath.item == 0) - reuseIdentifier = NSStringFromClass( [MPPasswordLargeDeleteCell class] ); - else if (type & MPElementTypeClassGenerated) + if (type & MPElementTypeClassGenerated) reuseIdentifier = NSStringFromClass( [MPPasswordLargeGeneratedCell class] ); else if (type & MPElementTypeClassStored) reuseIdentifier = NSStringFromClass( [MPPasswordLargeStoredCell class] ); else - Throw(@"Unexpected password type: %@", [MPAlgorithmDefault nameOfType:type]); + Throw( @"Unexpected password type: %@", [MPAlgorithmDefault nameOfType:type] ); MPPasswordLargeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; cell.type = type; @@ -68,73 +65,63 @@ [super prepareForReuse]; } -- (void)reloadWithTransientSite:(NSString *)siteName { - - self.nameLabel.text = strl( @"%@ - Tap to create", siteName ); +- (void)update { self.loginButton.alpha = 0; self.upgradeButton.alpha = 0; - self.typeLabel.text = [MPAlgorithmDefault nameOfType:self.type]; - if (self.type & MPElementTypeClassStored) { - self.contentField.enabled = YES; - self.contentField.placeholder = strl( @"Set custom password" ); - } - else if (self.type & MPElementTypeClassGenerated) { - self.contentField.enabled = NO; - self.contentField.placeholder = strl( @"Generating..." ); - } - else { - self.contentField.enabled = NO; - self.contentField.placeholder = nil; - } + self.nameLabel.text = @""; + self.typeLabel.text = @""; + self.contentField.text = @""; + self.contentField.placeholder = nil; + self.contentField.enabled = self.contentFieldMode == MPContentFieldModeUser; + self.loginButton.selected = self.contentFieldMode == MPContentFieldModeUser; + + switch (self.contentFieldMode) { + case MPContentFieldModePassword: { + if (self.type & MPElementTypeClassStored) + self.contentField.placeholder = strl( @"Set custom password" ); + else if (self.type & MPElementTypeClassGenerated) + self.contentField.placeholder = strl( @"Generating..." ); + break; + } + case MPContentFieldModeUser: { + self.contentField.placeholder = strl( @"Enter your login name" ); + break; + } + } +} + +- (void)updateWithTransientSite:(NSString *)siteName { + + [self update]; + + self.nameLabel.text = strl( @"%@ - Tap to create", siteName ); + self.typeLabel.text = [MPAlgorithmDefault nameOfType:self.type]; - self.contentField.text = nil; [self resolveContentOfCellTypeForTransientSite:siteName usingKey:[MPiOSAppDelegate get].key result:^(NSString *string) { PearlMainQueue( ^{ self.contentField.text = string; } ); }]; } -- (void)reloadWithElement:(MPElementEntity *)mainElement { +- (void)updateWithElement:(MPElementEntity *)mainElement { - if (!mainElement) { - self.loginButton.alpha = 0; - self.upgradeButton.alpha = 0; - self.typeLabel.text = @""; - self.nameLabel.text = @""; - self.contentField.text = @""; + [self update]; + + if (!mainElement) return; - } self.loginButton.alpha = 1; - if (mainElement.requiresExplicitMigration) self.upgradeButton.alpha = 1; - else - self.upgradeButton.alpha = 0; + self.nameLabel.text = mainElement.name; if (self.type == (MPElementType)NSNotFound) self.typeLabel.text = @"Delete"; else self.typeLabel.text = [mainElement.algorithm nameOfType:self.type]; - self.nameLabel.text = mainElement.name; - switch (self.contentFieldMode) { case MPContentFieldModePassword: { - if (self.type & MPElementTypeClassStored) { - self.contentField.enabled = YES; - self.contentField.placeholder = strl( @"Set custom password" ); - } - else if (self.type & MPElementTypeClassGenerated) { - self.contentField.enabled = NO; - self.contentField.placeholder = strl( @"Generating..." ); - } - else { - self.contentField.enabled = NO; - self.contentField.placeholder = nil; - } - - self.contentField.text = nil; MPKey *key = [MPiOSAppDelegate get].key; if (self.type == mainElement.type) [mainElement resolveContentUsingKey:key result:^(NSString *string) { @@ -147,20 +134,18 @@ break; } case MPContentFieldModeUser: { - self.contentField.enabled = YES; - self.contentField.placeholder = strl( @"Enter login name" ); self.contentField.text = mainElement.loginName; break; } } } -- (void)resolveContentOfCellTypeForTransientSite:(NSString *)siteName usingKey:(MPKey *)key result:(void (^)(NSString *))resultBlock { +- (void)resolveContentOfCellTypeForTransientSite:(NSString *)siteName usingKey:(MPKey *)key result:(void ( ^ )(NSString *))resultBlock { resultBlock( nil ); } -- (void)resolveContentOfCellTypeForElement:(MPElementEntity *)element usingKey:(MPKey *)key result:(void (^)(NSString *))resultBlock { +- (void)resolveContentOfCellTypeForElement:(MPElementEntity *)element usingKey:(MPKey *)key result:(void ( ^ )(NSString *))resultBlock { resultBlock( nil ); } @@ -182,27 +167,22 @@ if (textField == self.contentField) { NSString *newContent = textField.text; + textField.enabled = NO; - [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { - MPElementEntity *element = [[MPPasswordTypesCell findAsSuperviewOf:self] elementInContext:context]; - if (!element) - return; + if (self.contentFieldMode == MPContentFieldModeUser) + [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { + MPElementEntity *element = [[MPPasswordTypesCell findAsSuperviewOf:self] elementInContext:context]; + if (!element) + return; - switch (self.contentFieldMode) { - case MPContentFieldModePassword: - break; - case MPContentFieldModeUser: { - element.loginName = newContent; - [context saveToStore]; + element.loginName = newContent; + [context saveToStore]; - PearlMainQueue( ^{ - [self updateAnimated:YES]; - [PearlOverlay showTemporaryOverlayWithTitle:@"Login Updated" dismissAfter:2]; - } ); - break; - } - } - }]; + PearlMainQueue( ^{ + [self updateAnimated:YES]; + [PearlOverlay showTemporaryOverlayWithTitle:@"Login Updated" dismissAfter:2]; + } ); + }]; } } diff --git a/MasterPassword/ObjC/iOS/MPPasswordLargeGeneratedCell.m b/MasterPassword/ObjC/iOS/MPPasswordLargeGeneratedCell.m index 354c8eba..3f2229a8 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordLargeGeneratedCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordLargeGeneratedCell.m @@ -32,9 +32,9 @@ [self.counterButton addGestureRecognizer:gestureRecognizer]; } -- (void)reloadWithElement:(MPElementEntity *)mainElement { +- (void)updateWithElement:(MPElementEntity *)mainElement { - [super reloadWithElement:mainElement]; + [super updateWithElement:mainElement]; MPElementGeneratedEntity *generatedElement = [self generatedElement:mainElement]; if (generatedElement) diff --git a/MasterPassword/ObjC/iOS/MPPasswordLargeStoredCell.m b/MasterPassword/ObjC/iOS/MPPasswordLargeStoredCell.m index 269e5ed5..89525318 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordLargeStoredCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordLargeStoredCell.m @@ -1,12 +1,12 @@ /** - * Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com) - * - * See the enclosed file LICENSE for license information (LGPLv3). If you did - * not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt - * - * @author Maarten Billemont - * @license http://www.gnu.org/licenses/lgpl-3.0.txt - */ +* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com) +* +* See the enclosed file LICENSE for license information (LGPLv3). If you did +* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt +* +* @author Maarten Billemont +* @license http://www.gnu.org/licenses/lgpl-3.0.txt +*/ // // MPPasswordLargeGeneratedCell.h @@ -31,7 +31,7 @@ #pragma mark - Lifecycle -- (void)resolveContentOfCellTypeForElement:(MPElementEntity *)element usingKey:(MPKey *)key result:(void (^)(NSString *))resultBlock { +- (void)resolveContentOfCellTypeForElement:(MPElementEntity *)element usingKey:(MPKey *)key result:(void ( ^ )(NSString *))resultBlock { if (element.type & MPElementTypeClassStored) [element resolveContentUsingKey:key result:resultBlock]; @@ -50,14 +50,13 @@ return element; } - #pragma mark - Actions - (IBAction)doEditContent:(UIButton *)sender { - UITextField *field = self.contentField; - field.enabled = YES; - [field becomeFirstResponder]; + UITextField *textField = self.contentField; + textField.enabled = YES; + [textField becomeFirstResponder]; } #pragma mark - UITextFieldDelegate @@ -69,26 +68,20 @@ if (textField == self.contentField) { NSString *newContent = textField.text; - [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { - MPElementStoredEntity *storedElement = [self storedElementInContext:context]; - if (!storedElement) - return; + if (self.contentFieldMode == MPContentFieldModePassword) + [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { + MPElementStoredEntity *storedElement = [self storedElementInContext:context]; + if (!storedElement) + return; - switch (self.contentFieldMode) { - case MPContentFieldModePassword: { - [storedElement.algorithm saveContent:newContent toElement:storedElement usingKey:[MPiOSAppDelegate get].key]; - [context saveToStore]; + [storedElement.algorithm saveContent:newContent toElement:storedElement usingKey:[MPiOSAppDelegate get].key]; + [context saveToStore]; - PearlMainQueue( ^{ - [self updateAnimated:YES]; - [PearlOverlay showTemporaryOverlayWithTitle:@"Password Updated" dismissAfter:2]; - } ); - break; - } - case MPContentFieldModeUser: - break; - } - }]; + PearlMainQueue( ^{ + [self updateAnimated:YES]; + [PearlOverlay showTemporaryOverlayWithTitle:@"Password Updated" dismissAfter:2]; + } ); + }]; } } diff --git a/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m b/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m index 0dc15c50..c316d21d 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m @@ -20,6 +20,7 @@ #import "MPPasswordLargeCell.h" #import "MPiOSAppDelegate.h" #import "MPAppDelegate_Store.h" +#import "MPPasswordLargeDeleteCell.h" @implementation MPPasswordTypesCell { NSManagedObjectID *_elementOID; @@ -96,12 +97,18 @@ - (MPPasswordLargeCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { - MPPasswordLargeCell *cell = [MPPasswordLargeCell dequeueCellWithType:[self typeForContentIndexPath:indexPath] - fromCollectionView:collectionView atIndexPath:indexPath]; - if (self.transientSite) - [cell reloadWithTransientSite:self.transientSite]; + MPPasswordLargeCell *cell; + if (indexPath.item == 0) + cell = [MPPasswordLargeDeleteCell dequeueCellWithType:(MPElementType)NSNotFound fromCollectionView:collectionView + atIndexPath:indexPath]; else - [cell reloadWithElement:self.mainElement]; + cell = [MPPasswordLargeCell dequeueCellWithType:[self typeForContentIndexPath:indexPath] fromCollectionView:collectionView + atIndexPath:indexPath]; + + if (self.transientSite) + [cell updateWithTransientSite:self.transientSite]; + else + [cell updateWithElement:self.mainElement]; dbg_return( cell, indexPath ); } @@ -209,16 +216,25 @@ if (self.transientSite) PearlMainQueue( ^{ - [self.contentCollectionView reloadData]; self.activeType = IfElse( [[MPiOSAppDelegate get] activeUserForMainThread].defaultType, MPElementTypeGeneratedLong ); + + for (NSInteger section = 0; section < [self.contentCollectionView numberOfSections]; ++section) + for (NSInteger item = 0; item < [self.contentCollectionView numberOfItemsInSection:section]; ++item) + [(MPPasswordLargeCell *)[self.contentCollectionView cellForItemAtIndexPath: + [NSIndexPath indexPathForItem:item inSection:section]] updateWithTransientSite:self.transientSite]; + } ); else [MPiOSAppDelegate managedObjectContextForMainThreadPerformBlockAndWait:^(NSManagedObjectContext *mainContext) { MPElementEntity *mainElement = [self mainElement]; self.algorithm = IfNotNilElse( mainElement.algorithm, MPAlgorithmDefault ); - [self.contentCollectionView reloadData]; self.activeType = mainElement.type; + + for (NSInteger section = 0; section < [self.contentCollectionView numberOfSections]; ++section) + for (NSInteger item = 0; item < [self.contentCollectionView numberOfItemsInSection:section]; ++item) + [(MPPasswordLargeCell *)[self.contentCollectionView cellForItemAtIndexPath: + [NSIndexPath indexPathForItem:item inSection:section]] updateWithElement:mainElement]; }]; } diff --git a/MasterPassword/ObjC/iOS/MPPasswordsCoachmarkViewController.m b/MasterPassword/ObjC/iOS/MPPasswordsCoachmarkViewController.m index 15db14b4..1198589a 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordsCoachmarkViewController.m +++ b/MasterPassword/ObjC/iOS/MPPasswordsCoachmarkViewController.m @@ -32,14 +32,14 @@ if (indexPath.item == 0) { MPPasswordLargeGeneratedCell *cell = [MPPasswordLargeGeneratedCell dequeueCellWithType:MPElementTypeGeneratedLong fromCollectionView:collectionView atIndexPath:indexPath]; - [cell reloadWithTransientSite:@"apple.com"]; + [cell updateWithTransientSite:@"apple.com"]; return cell; } else if (indexPath.item == 1) { MPPasswordLargeStoredCell *cell = [MPPasswordLargeStoredCell dequeueCellWithType:MPElementTypeStoredPersonal fromCollectionView:collectionView atIndexPath:indexPath]; - [cell reloadWithTransientSite:@"gmail.com"]; + [cell updateWithTransientSite:@"gmail.com"]; [cell.contentField setText:@"PaS$w0rD"]; return cell; diff --git a/MasterPassword/ObjC/iOS/MPPreferencesViewController.h b/MasterPassword/ObjC/iOS/MPPreferencesViewController.h index a33e1f79..a865d42f 100644 --- a/MasterPassword/ObjC/iOS/MPPreferencesViewController.h +++ b/MasterPassword/ObjC/iOS/MPPreferencesViewController.h @@ -12,6 +12,7 @@ @interface MPPreferencesViewController : UITableViewController @property(weak, nonatomic) IBOutlet UISwitch *savePasswordSwitch; +@property(weak, nonatomic) IBOutlet UITableViewCell *signOutCell; @property(weak, nonatomic) IBOutlet UITableViewCell *feedbackCell; @property(weak, nonatomic) IBOutlet UITableViewCell *coachmarksCell; @property(weak, nonatomic) IBOutlet UITableViewCell *exportCell; diff --git a/MasterPassword/ObjC/iOS/MPPreferencesViewController.m b/MasterPassword/ObjC/iOS/MPPreferencesViewController.m index 82a493bf..d51b04f1 100644 --- a/MasterPassword/ObjC/iOS/MPPreferencesViewController.m +++ b/MasterPassword/ObjC/iOS/MPPreferencesViewController.m @@ -57,18 +57,18 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; + if (cell == self.signOutCell) { + MPPasswordsViewController *passwordsVC = [self dismissPopup]; + [[MPiOSAppDelegate get] signOutAnimated:YES]; + } if (cell == self.feedbackCell) [[MPiOSAppDelegate get] showFeedbackWithLogs:YES forVC:self]; if (cell == self.exportCell) [[MPiOSAppDelegate get] showExportForVC:self]; if (cell == self.coachmarksCell) { - for (UIViewController *vc = self; (vc = vc.parentViewController);) - if ([vc isKindOfClass:[MPPasswordsViewController class]]) { - MPPasswordsViewController *passwordsVC = (MPPasswordsViewController *)vc; - passwordsVC.coachmark.coached = NO; - [passwordsVC dismissPopdown:self]; - [vc performSegueWithIdentifier:@"coachmarks" sender:self]; - } + MPPasswordsViewController *passwordsVC = [self dismissPopup]; + passwordsVC.coachmark.coached = NO; + [passwordsVC performSegueWithIdentifier:@"coachmarks" sender:self]; } if (cell == self.checkInconsistencies) [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { @@ -144,6 +144,18 @@ #pragma mark - Private +- (MPPasswordsViewController *)dismissPopup { + + for (UIViewController *vc = self; (vc = vc.parentViewController);) + if ([vc isKindOfClass:[MPPasswordsViewController class]]) { + MPPasswordsViewController *passwordsVC = (MPPasswordsViewController *)vc; + [passwordsVC dismissPopdown:self]; + return passwordsVC; + } + + return nil; +} + - (enum MPElementType)typeForSelectedSegment { NSInteger selectedGeneratedIndex = self.generatedTypeControl.selectedSegmentIndex; @@ -170,7 +182,8 @@ case 1: return MPElementTypeStoredDevicePrivate; default: - Throw( @"unsupported selected type index: generated=%ld, stored=%ld", (long)selectedGeneratedIndex, (long)selectedStoredIndex ); + Throw( @"unsupported selected type index: generated=%ld, stored=%ld", (long)selectedGeneratedIndex, + (long)selectedStoredIndex ); } } } diff --git a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj index 2fc0dada..27fe8b30 100644 --- a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -274,6 +274,8 @@ DAC6326D148680650075AEA5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; DAC632891486D9690075AEA5 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC632871486D95D0075AEA5 /* Security.framework */; }; DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; + DAC8DF47192831E100BA7D71 /* icon_key.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD379A1711E29600CF925C /* icon_key.png */; }; + DAC8DF48192831E100BA7D71 /* icon_key@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD379B1711E29600CF925C /* icon_key@2x.png */; }; DACA22BB1705DE7D002C6C22 /* UbiquityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DACA22B71705DE7D002C6C22 /* UbiquityStoreManager.m */; }; DACA22BC1705DE7D002C6C22 /* NSError+UbiquityStoreManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA22B81705DE7D002C6C22 /* NSError+UbiquityStoreManager.h */; }; DACA22BD1705DE7D002C6C22 /* NSError+UbiquityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DACA22B91705DE7D002C6C22 /* NSError+UbiquityStoreManager.m */; }; @@ -3673,6 +3675,8 @@ DABD39471711E29700CF925C /* avatar-16@2x.png in Resources */, DABD39481711E29700CF925C /* avatar-17.png in Resources */, DABD39491711E29700CF925C /* avatar-17@2x.png in Resources */, + DAC8DF47192831E100BA7D71 /* icon_key.png in Resources */, + DAC8DF48192831E100BA7D71 /* icon_key@2x.png in Resources */, DABD394A1711E29700CF925C /* avatar-18.png in Resources */, DABD394B1711E29700CF925C /* avatar-18@2x.png in Resources */, DABD394C1711E29700CF925C /* avatar-1@2x.png in Resources */, diff --git a/MasterPassword/ObjC/iOS/Storyboard.storyboard b/MasterPassword/ObjC/iOS/Storyboard.storyboard index 8f3daff4..2bd6b34d 100644 --- a/MasterPassword/ObjC/iOS/Storyboard.storyboard +++ b/MasterPassword/ObjC/iOS/Storyboard.storyboard @@ -1,5 +1,5 @@ - + @@ -19,7 +19,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -122,7 +122,7 @@ - - - + @@ -502,8 +502,42 @@ + + + + + + + + + + + + + + + + + + + + + + - + @@ -569,7 +603,7 @@ - + @@ -649,7 +683,7 @@ - + @@ -693,7 +727,7 @@ - + @@ -727,7 +761,7 @@ - + @@ -761,7 +795,7 @@ - + @@ -795,7 +829,7 @@ - + @@ -848,6 +882,7 @@ + @@ -912,8 +947,8 @@ - - + @@ -2390,13 +2393,13 @@ However, it means that anyone who finds your device unlocked can do the same. - + - + @@ -2417,7 +2420,6 @@ However, it means that anyone who finds your device unlocked can do the same. - @@ -2425,12 +2427,12 @@ However, it means that anyone who finds your device unlocked can do the same. - + - + @@ -2438,67 +2440,13 @@ However, it means that anyone who finds your device unlocked can do the same. - + - - - - - - - + + + + + + + + + + + + + - + + + @@ -2529,8 +2540,8 @@ to change password type - - + + @@ -2540,7 +2551,7 @@ to change password type - + @@ -2570,6 +2581,15 @@ to change password type + + + + + + + + +