From 6e14554f95689ec2aa6fb5dec20918fbcce81ca4 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Thu, 11 Sep 2014 00:26:01 -0400 Subject: [PATCH] Weird layout problems now when building from Xcode 6.. --- External/Pearl | 2 +- MasterPassword/ObjC/iOS/MPAvatarCell.m | 185 +++++++++--------- .../ObjC/iOS/MPPasswordsViewController.m | 2 + .../ObjC/iOS/MPUsersViewController.h | 2 - .../ObjC/iOS/MPUsersViewController.m | 181 ++++++++--------- .../project.pbxproj | 4 +- MasterPassword/ObjC/iOS/Storyboard.storyboard | 9 +- 7 files changed, 191 insertions(+), 194 deletions(-) diff --git a/External/Pearl b/External/Pearl index 6f399ecc..047cab4e 160000 --- a/External/Pearl +++ b/External/Pearl @@ -1 +1 @@ -Subproject commit 6f399eccdc5cc016cdc898778845675bbe624cd3 +Subproject commit 047cab4e60a35090eb901e61d9fd76e55afff0ac diff --git a/MasterPassword/ObjC/iOS/MPAvatarCell.m b/MasterPassword/ObjC/iOS/MPAvatarCell.m index 6ae32a8f..0c1db32f 100644 --- a/MasterPassword/ObjC/iOS/MPAvatarCell.m +++ b/MasterPassword/ObjC/iOS/MPAvatarCell.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 @@ -88,9 +88,9 @@ const long MPAvatarAdd = 10000; [super prepareForReuse]; _newUser = NO; - [self setVisibility:0 animated:NO]; - [self setMode:MPAvatarModeLowered animated:NO]; - [self setSpinnerActive:NO animated:NO]; + _visibility = 0; + _mode = MPAvatarModeLowered; + _spinnerActive = NO; } - (void)dealloc { @@ -130,6 +130,8 @@ const long MPAvatarAdd = 10000; - (void)setVisibility:(CGFloat)visibility animated:(BOOL)animated { + if (visibility == _visibility) + return; _visibility = visibility; [self updateAnimated:animated]; @@ -149,6 +151,8 @@ const long MPAvatarAdd = 10000; - (void)setMode:(MPAvatarMode)mode animated:(BOOL)animated { + if (mode == _mode) + return; _mode = mode; [self updateAnimated:animated]; @@ -189,92 +193,95 @@ const long MPAvatarAdd = 10000; - (void)updateAnimated:(BOOL)animated { + [self.contentView layoutIfNeeded]; [UIView animateWithDuration:animated? 0.2f: 0 animations:^{ self.avatarImageView.transform = CGAffineTransformIdentity; }]; - [UIView animateWithDuration:animated? 0.3f: 0 delay:0 options:UIViewAnimationOptionOverrideInheritedDuration animations:^{ - self.alpha = 1; + [UIView animateWithDuration:animated? 0.7f: 0 delay:0 + options:UIViewAnimationOptionOverrideInheritedDuration | UIViewAnimationOptionBeginFromCurrentState + animations:^{ + self.alpha = 1; - if (self.newUser) { - if (self.mode == MPAvatarModeLowered) - self.avatar = MPAvatarAdd; - else if (self.avatar == MPAvatarAdd) - self.avatar = arc4random() % MPAvatarCount; - } + if (self.newUser) { + if (self.mode == MPAvatarModeLowered) + self.avatar = MPAvatarAdd; + else if (self.avatar == MPAvatarAdd) + self.avatar = arc4random() % MPAvatarCount; + } - switch (self.mode) { - case MPAvatarModeLowered: { - [self.avatarSizeConstraint updateConstant:self.avatarImageView.image.size.height]; - [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultLow]; - [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultLow]; - [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultLow]; - self.nameContainer.alpha = self.visibility; - self.nameContainer.backgroundColor = [UIColor clearColor]; - self.avatarImageView.alpha = self.visibility / 0.7f + 0.3f; - self.avatarImageView.layer.shadowRadius = 15 * self.visibility * self.visibility; - break; - } - case MPAvatarModeRaisedButInactive: { - [self.avatarSizeConstraint updateConstant:self.avatarImageView.image.size.height]; - [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultHigh]; - [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultLow]; - [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultLow]; - self.nameContainer.alpha = self.visibility; - self.nameContainer.backgroundColor = [UIColor clearColor]; - self.avatarImageView.alpha = 0; - self.avatarImageView.layer.shadowRadius = 15 * self.visibility * self.visibility; - break; - } - case MPAvatarModeRaisedAndActive: { - [self.avatarSizeConstraint updateConstant:self.avatarImageView.image.size.height]; - [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultHigh]; - [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultLow]; - [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultHigh]; - self.nameContainer.alpha = self.visibility; - self.nameContainer.backgroundColor = [UIColor blackColor]; - self.avatarImageView.alpha = 1; - self.avatarImageView.layer.shadowRadius = 15 * self.visibility * self.visibility; - break; - } - case MPAvatarModeRaisedAndHidden: { - [self.avatarSizeConstraint updateConstant:self.avatarImageView.image.size.height]; - [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultHigh]; - [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultLow]; - [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultHigh]; - self.nameContainer.alpha = 0; - self.nameContainer.backgroundColor = [UIColor blackColor]; - self.avatarImageView.alpha = 0; - self.avatarImageView.layer.shadowRadius = 15 * self.visibility * self.visibility; - break; - } - case MPAvatarModeRaisedAndMinimized: { - [self.avatarSizeConstraint updateConstant:36]; - [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultLow]; - [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultHigh]; - [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultHigh]; - self.nameContainer.alpha = 0; - self.nameContainer.backgroundColor = [UIColor blackColor]; - self.avatarImageView.alpha = 1; - break; - } - } + switch (self.mode) { + case MPAvatarModeLowered: { + [self.avatarSizeConstraint updateConstant:self.avatarImageView.image.size.height]; + [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultLow]; + [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultLow]; + [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultLow]; + self.nameContainer.alpha = self.visibility; + self.nameContainer.backgroundColor = [UIColor clearColor]; + self.avatarImageView.alpha = self.visibility / 0.7f + 0.3f; + self.avatarImageView.layer.shadowRadius = 15 * self.visibility * self.visibility; + break; + } + case MPAvatarModeRaisedButInactive: { + [self.avatarSizeConstraint updateConstant:self.avatarImageView.image.size.height]; + [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultHigh]; + [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultLow]; + [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultLow]; + self.nameContainer.alpha = self.visibility; + self.nameContainer.backgroundColor = [UIColor clearColor]; + self.avatarImageView.alpha = 0; + self.avatarImageView.layer.shadowRadius = 15 * self.visibility * self.visibility; + break; + } + case MPAvatarModeRaisedAndActive: { + [self.avatarSizeConstraint updateConstant:self.avatarImageView.image.size.height]; + [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultHigh]; + [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultLow]; + [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultHigh]; + self.nameContainer.alpha = self.visibility; + self.nameContainer.backgroundColor = [UIColor blackColor]; + self.avatarImageView.alpha = 1; + self.avatarImageView.layer.shadowRadius = 15 * self.visibility * self.visibility; + break; + } + case MPAvatarModeRaisedAndHidden: { + [self.avatarSizeConstraint updateConstant:self.avatarImageView.image.size.height]; + [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultHigh]; + [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultLow]; + [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultHigh]; + self.nameContainer.alpha = 0; + self.nameContainer.backgroundColor = [UIColor blackColor]; + self.avatarImageView.alpha = 0; + self.avatarImageView.layer.shadowRadius = 15 * self.visibility * self.visibility; + break; + } + case MPAvatarModeRaisedAndMinimized: { + [self.avatarSizeConstraint updateConstant:36]; + [self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultLow]; + [self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultHigh]; + [self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultHigh]; + self.nameContainer.alpha = 0; + self.nameContainer.backgroundColor = [UIColor blackColor]; + self.avatarImageView.alpha = 1; + break; + } + } - // Avatar minimized. - if (self.mode == MPAvatarModeRaisedAndMinimized) - [self.avatarImageView.layer removeAllAnimations]; - else if (![self.avatarImageView.layer animationForKey:@"targetedShadow"]) - [self.avatarImageView.layer addAnimation:_targetedShadowAnimation forKey:@"targetedShadow"]; + // Avatar minimized. + if (self.mode == MPAvatarModeRaisedAndMinimized) + [self.avatarImageView.layer removeAnimationForKey:@"targetedShadow"]; + else if (![self.avatarImageView.layer animationForKey:@"targetedShadow"]) + [self.avatarImageView.layer addAnimation:_targetedShadowAnimation forKey:@"targetedShadow"]; - // Avatar selection and spinner. - if (self.mode != MPAvatarModeRaisedAndMinimized && (self.selected || self.highlighted) && !self.spinnerActive) - self.avatarImageView.backgroundColor = self.avatarImageView.tintColor; - else - self.avatarImageView.backgroundColor = [UIColor clearColor]; - self.avatarImageView.layer.cornerRadius = self.avatarImageView.bounds.size.height / 2; - self.spinner.alpha = self.spinnerActive? 1: 0; + // Avatar selection and spinner. + if (self.mode != MPAvatarModeRaisedAndMinimized && (self.selected || self.highlighted) && !self.spinnerActive) + self.avatarImageView.backgroundColor = self.avatarImageView.tintColor; + else + self.avatarImageView.backgroundColor = [UIColor clearColor]; + self.avatarImageView.layer.cornerRadius = self.avatarImageView.bounds.size.height / 2; + self.spinner.alpha = self.spinnerActive? 1: 0; - [self layoutSubviews]; - } completion:nil]; + [self.contentView layoutIfNeeded]; + } completion:nil]; } @end diff --git a/MasterPassword/ObjC/iOS/MPPasswordsViewController.m b/MasterPassword/ObjC/iOS/MPPasswordsViewController.m index fb776cee..4a85e432 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordsViewController.m +++ b/MasterPassword/ObjC/iOS/MPPasswordsViewController.m @@ -215,6 +215,7 @@ referenceSizeForHeaderInSection:(NSInteger)section { if (_passwordsDismissRecognizer) [self.view removeGestureRecognizer:_passwordsDismissRecognizer]; + [self updatePasswords]; [UIView animateWithDuration:0.3f animations:^{ self.passwordCollectionView.backgroundColor = _backgroundColor; }]; @@ -223,6 +224,7 @@ referenceSizeForHeaderInSection:(NSInteger)section { - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { + searchBar.text = nil; [searchBar resignFirstResponder]; } diff --git a/MasterPassword/ObjC/iOS/MPUsersViewController.h b/MasterPassword/ObjC/iOS/MPUsersViewController.h index 5e2118b1..dac5b01a 100644 --- a/MasterPassword/ObjC/iOS/MPUsersViewController.h +++ b/MasterPassword/ObjC/iOS/MPUsersViewController.h @@ -19,7 +19,6 @@ @interface MPUsersViewController : UIViewController -@property (strong, nonatomic) IBOutlet UINavigationBar *navigationBar; @property(weak, nonatomic) IBOutlet UIView *userSelectionContainer; @property(weak, nonatomic) IBOutlet UIButton *marqueeButton; @property(weak, nonatomic) IBOutlet UIView *gitTipTip; @@ -32,7 +31,6 @@ @property(weak, nonatomic) IBOutlet UIView *footerContainer; @property(weak, nonatomic) IBOutlet UIActivityIndicatorView *storeLoadingActivity; @property(weak, nonatomic) IBOutlet UICollectionView *avatarCollectionView; -@property (strong, nonatomic) IBOutlet NSLayoutConstraint *navigationBarToTopConstraint; @property (strong, nonatomic) IBOutlet UIButton *nextAvatarButton; @property (strong, nonatomic) IBOutlet UIButton *previousAvatarButton; diff --git a/MasterPassword/ObjC/iOS/MPUsersViewController.m b/MasterPassword/ObjC/iOS/MPUsersViewController.m index 705ecab3..c146822d 100644 --- a/MasterPassword/ObjC/iOS/MPUsersViewController.m +++ b/MasterPassword/ObjC/iOS/MPUsersViewController.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 +*/ // // MPCombinedViewController.h @@ -26,7 +26,7 @@ #import "MPWebViewController.h" #import "UIView+FontScale.h" -typedef NS_ENUM(NSUInteger, MPActiveUserState) { +typedef NS_ENUM( NSUInteger, MPActiveUserState ) { /** The users are all inactive */ MPActiveUserStateNone, /** The selected user is activated and being logged in with */ @@ -73,7 +73,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { self.view.backgroundColor = [UIColor clearColor]; self.avatarCollectionView.allowsMultipleSelection = YES; - [self.entryField addTarget:self action:@selector(textFieldEditingChanged:) forControlEvents:UIControlEventEditingChanged]; + [self.entryField addTarget:self action:@selector( textFieldEditingChanged: ) forControlEvents:UIControlEventEditingChanged]; [self setActive:YES animated:NO]; } @@ -89,7 +89,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { [self reloadUsers]; [self.marqueeTipTimer invalidate]; - self.marqueeTipTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(firedMarqueeTimer:) + self.marqueeTipTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector( firedMarqueeTimer: ) userInfo:nil repeats:YES]; [self firedMarqueeTimer:nil]; } @@ -266,7 +266,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { return CGSizeMake( parentSize.width / 2, parentSize.height ); } - Throw(@"unexpected collection view: %@", collectionView); + Throw( @"unexpected collection view: %@", collectionView ); } #pragma mark - UICollectionViewDataSource @@ -276,14 +276,14 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { if (collectionView == self.avatarCollectionView) return [self.userIDs count] + 1; - Throw(@"unexpected collection view: %@", collectionView); + Throw( @"unexpected collection view: %@", collectionView ); } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { if (collectionView == self.avatarCollectionView) { MPAvatarCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[MPAvatarCell reuseIdentifier] forIndexPath:indexPath]; - [cell addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongPress:)]]; + [cell addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector( didLongPress: )]]; [self updateModeForAvatar:cell atIndexPath:indexPath animated:NO]; [self updateVisibilityForAvatar:cell atIndexPath:indexPath animated:NO]; @@ -291,7 +291,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { MPUserEntity *user = [self userForIndexPath:indexPath inContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady] isNew:&isNew]; if (isNew) - // New User + // New User cell.avatar = MPAvatarAdd; else { // Existing User @@ -302,7 +302,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { return cell; } - Throw(@"unexpected collection view: %@", collectionView); + Throw( @"unexpected collection view: %@", collectionView ); } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { @@ -357,7 +357,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { if ([recognizer.view isKindOfClass:[MPAvatarCell class]]) { if (recognizer.state != UIGestureRecognizerStateBegan) - // Don't show the action menu unless the state is Began. + // Don't show the action menu unless the state is Began. return; MPAvatarCell *avatarCell = (MPAvatarCell *)recognizer.view; @@ -372,40 +372,40 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { [PearlSheet showSheetWithTitle:user.name viewStyle:UIActionSheetStyleBlackTranslucent initSheet:nil tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) { - if (buttonIndex == [sheet cancelButtonIndex]) - return; - - if (buttonIndex == [sheet destructiveButtonIndex]) { - // Delete User - [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { - MPUserEntity *user_ = [MPUserEntity existingObjectWithID:userID inContext:context]; - if (!user_) + if (buttonIndex == [sheet cancelButtonIndex]) return; - [context deleteObject:user_]; - [context saveToStore]; - [self reloadUsers]; // I do NOT understand why our ObjectsDidChangeNotification isn't firing on saveToStore. - }]; - return; - } + if (buttonIndex == [sheet destructiveButtonIndex]) { + // Delete User + [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { + MPUserEntity *user_ = [MPUserEntity existingObjectWithID:userID inContext:context]; + if (!user_) + return; - if (buttonIndex == [sheet firstOtherButtonIndex]) - // Reset Password - [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { - MPUserEntity *user_ = [MPUserEntity existingObjectWithID:userID inContext:context]; - if (!user_) + [context deleteObject:user_]; + [context saveToStore]; + [self reloadUsers]; // I do NOT understand why our ObjectsDidChangeNotification isn't firing on saveToStore. + }]; return; + } - [[MPiOSAppDelegate get] changeMasterPasswordFor:user_ saveInContext:context didResetBlock:^{ - PearlMainQueue( ^{ - NSIndexPath *avatarIndexPath = [self.avatarCollectionView indexPathForCell:avatarCell]; - [self.avatarCollectionView selectItemAtIndexPath:avatarIndexPath animated:NO - scrollPosition:UICollectionViewScrollPositionNone]; - [self collectionView:self.avatarCollectionView didSelectItemAtIndexPath:avatarIndexPath]; - } ); - }]; - }]; - } cancelTitle:[PearlStrings get].commonButtonCancel + if (buttonIndex == [sheet firstOtherButtonIndex]) + // Reset Password + [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { + MPUserEntity *user_ = [MPUserEntity existingObjectWithID:userID inContext:context]; + if (!user_) + return; + + [[MPiOSAppDelegate get] changeMasterPasswordFor:user_ saveInContext:context didResetBlock:^{ + PearlMainQueue( ^{ + NSIndexPath *avatarIndexPath = [self.avatarCollectionView indexPathForCell:avatarCell]; + [self.avatarCollectionView selectItemAtIndexPath:avatarIndexPath animated:NO + scrollPosition:UICollectionViewScrollPositionNone]; + [self collectionView:self.avatarCollectionView didSelectItemAtIndexPath:avatarIndexPath]; + } ); + }]; + }]; + } cancelTitle:[PearlStrings get].commonButtonCancel destructiveTitle:@"Delete User" otherTitles:@"Reset Password", nil]; } } @@ -421,7 +421,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { CGPointPlusCGPoint( *targetContentOffset, offsetToCenter )]; CGPoint targetCenter = [self.avatarCollectionView layoutAttributesForItemAtIndexPath:avatarIndexPath].center; *targetContentOffset = CGPointMinusCGPoint( targetCenter, offsetToCenter ); - NSAssert([self.avatarCollectionView indexPathForItemAtPoint:targetCenter].item == avatarIndexPath.item, @"should be same item"); + NSAssert( [self.avatarCollectionView indexPathForItemAtPoint:targetCenter].item == avatarIndexPath.item, @"should be same item" ); } } @@ -502,19 +502,14 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { return [MPUserEntity existingObjectWithID:self.userIDs[indexPath.item] inContext:context]; } -- (void)updateAvatars { +- (void)updateAvatarVisibility { self.previousAvatarButton.alpha = 0; self.nextAvatarButton.alpha = 0; - for (NSIndexPath *indexPath in self.avatarCollectionView.indexPathsForVisibleItems) - [self updateAvatarAtIndexPath:indexPath]; -} - -- (void)updateAvatarAtIndexPath:(NSIndexPath *)indexPath { - - MPAvatarCell *cell = (MPAvatarCell *)[self.avatarCollectionView cellForItemAtIndexPath:indexPath]; - [self updateModeForAvatar:cell atIndexPath:indexPath animated:NO]; - [self updateVisibilityForAvatar:cell atIndexPath:indexPath animated:NO]; + for (NSIndexPath *indexPath in self.avatarCollectionView.indexPathsForVisibleItems) { + MPAvatarCell *cell = (MPAvatarCell *)[self.avatarCollectionView cellForItemAtIndexPath:indexPath]; + [self updateVisibilityForAvatar:cell atIndexPath:indexPath animated:NO]; + } } - (void)updateModeForAvatar:(MPAvatarCell *)avatarCell atIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated { @@ -551,7 +546,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { self.avatarCollectionView.contentOffset.x; CGFloat max = self.avatarCollectionView.bounds.size.width; - CGFloat visibility = MAX(0, MIN( 1, 1 - ABS( current / (max / 2) - 1 ) )); + CGFloat visibility = MAX( 0, MIN( 1, 1 - ABS( current / (max / 2) - 1 ) ) ); [cell setVisibility:visibility animated:animated]; if (cell.newUser) { @@ -560,7 +555,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { } } -- (void)afterUpdatesMainQueue:(void (^)(void))block { +- (void)afterUpdatesMainQueue:(void ( ^ )(void))block { [_afterUpdates addOperationWithBlock:^{ PearlMainQueue( block ); @@ -572,32 +567,32 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { if ([_notificationObservers count]) return; - Weakify(self); + Weakify( self ); _notificationObservers = @[ [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { - Strongify(self); + Strongify( self ); // [self emergencyCloseAnimated:NO]; - self.userSelectionContainer.alpha = 0; - }], + self.userSelectionContainer.alpha = 0; + }], [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { - Strongify(self); + Strongify( self ); - [self reloadUsers]; + [self reloadUsers]; - [UIView animateWithDuration:1 animations:^{ - self.userSelectionContainer.alpha = 1; - }]; - }], + [UIView animateWithDuration:1 animations:^{ + self.userSelectionContainer.alpha = 1; + }]; + }], ]; [self observeKeyPath:@"avatarCollectionView.contentOffset" withBlock: ^(id from, id to, NSKeyValueChange cause, MPUsersViewController *_self) { - [_self updateAvatars]; + [_self updateAvatarVisibility]; }]; } @@ -612,7 +607,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { - (void)observeStore { - Weakify(self); + Weakify( self ); NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady]; [UIView animateWithDuration:0.3f animations:^{ @@ -627,10 +622,10 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { _mocObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextObjectsDidChangeNotification object:mainContext queue:nil usingBlock:^(NSNotification *note) { - Strongify(self); + Strongify( self ); NSSet *insertedObjects = note.userInfo[NSInsertedObjectsKey]; NSSet *deletedObjects = note.userInfo[NSDeletedObjectsKey]; - if ([[NSSetUnion(insertedObjects, deletedObjects) + if ([[NSSetUnion( insertedObjects, deletedObjects ) filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { return [evaluatedObject isKindOfClass:[MPUserEntity class]]; }]] count]) @@ -640,7 +635,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { _storeChangingObserver = [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreWillChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) { - Strongify(self); + Strongify( self ); if (self->_mocObserver) [[NSNotificationCenter defaultCenter] removeObserver:self->_mocObserver]; }]; @@ -648,7 +643,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { _storeChangedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) { - Strongify(self); + Strongify( self ); [self reloadUsers]; }]; } @@ -671,11 +666,11 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { NSError *error = nil; NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPUserEntity class] )]; fetchRequest.sortDescriptors = @[ - [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector( @selector(lastUsed) ) ascending:NO] + [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO] ]; NSArray *users = [mainContext executeFetchRequest:fetchRequest error:&error]; if (!users) { - err(@"Failed to load users: %@", error); + err( @"Failed to load users: %@", error ); self.userIDs = nil; } @@ -742,24 +737,11 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { return; } + // Set the entry container's contents. [_afterUpdates setSuspended:YES]; __block BOOL requestFirstResponder = NO; + [self.view layoutIfNeeded]; [UIView animateWithDuration:animated? 0.4f: 0 animations:^{ - MPAvatarCell *selectedAvatar = [self selectedAvatar]; - - // Set avatar modes. - for (NSUInteger item = 0; item < [self.avatarCollectionView numberOfItemsInSection:0]; ++item) { - NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:0]; - MPAvatarCell *avatarCell = (MPAvatarCell *)[self.avatarCollectionView cellForItemAtIndexPath:indexPath]; - [self updateModeForAvatar:avatarCell atIndexPath:indexPath animated:animated]; - [self updateVisibilityForAvatar:avatarCell atIndexPath:indexPath animated:animated]; - - if (selectedAvatar && avatarCell == selectedAvatar) - [self.avatarCollectionView scrollToItemAtIndexPath:indexPath - atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO]; - } - - // Set the entry container's contents. switch (activeUserState) { case MPActiveUserStateNone: break; @@ -799,7 +781,6 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { // Manage the entry container depending on whether a user is activate or not. switch (activeUserState) { case MPActiveUserStateNone: { - [self.navigationBarToTopConstraint updatePriority:UILayoutPriorityDefaultHigh]; self.avatarCollectionView.scrollEnabled = YES; self.entryContainer.alpha = 0; self.footerContainer.alpha = 1; @@ -809,7 +790,6 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { case MPActiveUserStateUserName: case MPActiveUserStateMasterPasswordChoice: case MPActiveUserStateMasterPasswordConfirmation: { - [self.navigationBarToTopConstraint updatePriority:UILayoutPriorityDefaultHigh]; self.avatarCollectionView.scrollEnabled = NO; self.entryContainer.alpha = 1; self.footerContainer.alpha = 1; @@ -817,7 +797,6 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { break; } case MPActiveUserStateMinimized: { - [self.navigationBarToTopConstraint updatePriority:1]; self.avatarCollectionView.scrollEnabled = NO; self.entryContainer.alpha = 0; self.footerContainer.alpha = 0; @@ -833,6 +812,18 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { [self.entryField resignFirstResponder]; if (requestFirstResponder) [self.entryField becomeFirstResponder]; + + // Set avatar modes. + MPAvatarCell *selectedAvatar = [self selectedAvatar]; + for (NSIndexPath *indexPath in [self.avatarCollectionView indexPathsForVisibleItems]) { + MPAvatarCell *avatarCell = (MPAvatarCell *)[self.avatarCollectionView cellForItemAtIndexPath:indexPath]; + [self updateModeForAvatar:avatarCell atIndexPath:indexPath animated:animated]; + [self updateVisibilityForAvatar:avatarCell atIndexPath:indexPath animated:animated]; + + if (selectedAvatar && avatarCell == selectedAvatar) + [self.avatarCollectionView scrollToItemAtIndexPath:indexPath + atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES]; + } } #pragma mark - Actions diff --git a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj index 11e99119..8e4444c6 100644 --- a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -142,6 +142,7 @@ DA69540717D975D900BF294E /* icon_gears@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37851711E29500CF925C /* icon_gears@2x.png */; }; DA72BD7519C133BF00E6ACFE /* libscryptenc-ios-dev.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA72BD7419C133BF00E6ACFE /* libscryptenc-ios-dev.a */; }; DA72BD7919C137DE00E6ACFE /* libopensslcrypto-ios-dev.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA72BD7719C137D500E6ACFE /* libopensslcrypto-ios-dev.a */; }; + DA72BD7B19C1510C00E6ACFE /* UIView+FontScale.m in Sources */ = {isa = PBXBuildFile; fileRef = DACE2F6719BA6A2A0010F92E /* UIView+FontScale.m */; }; DA73049D194E022700E72520 /* ui_spinner.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD36511711E29400CF925C /* ui_spinner.png */; }; DA73049E194E022700E72520 /* ui_spinner@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD36521711E29400CF925C /* ui_spinner@2x.png */; }; DA73049F194E022B00E72520 /* ui_textfield.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD365B1711E29400CF925C /* ui_textfield.png */; }; @@ -274,7 +275,6 @@ DACA29BF1705E2DE002C6C22 /* UIColor+HSV.m in Sources */ = {isa = PBXBuildFile; fileRef = DACA29BB1705E2DE002C6C22 /* UIColor+HSV.m */; }; DACE2F6519BA6A0A0010F92E /* PearlProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = DACE2F6319BA6A0A0010F92E /* PearlProfiler.m */; }; DACE2F6619BA6A0A0010F92E /* PearlProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = DACE2F6419BA6A0A0010F92E /* PearlProfiler.h */; }; - DACE2F6B19BA6A2A0010F92E /* UIView+FontScale.m in Sources */ = {isa = PBXBuildFile; fileRef = DACE2F6719BA6A2A0010F92E /* UIView+FontScale.m */; }; DACE2F6C19BA6A2A0010F92E /* PearlMutableStaticTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DACE2F6819BA6A2A0010F92E /* PearlMutableStaticTableViewController.m */; }; DACE2F6D19BA6A2A0010F92E /* PearlMutableStaticTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = DACE2F6919BA6A2A0010F92E /* PearlMutableStaticTableViewController.h */; }; DACE2F6E19BA6A2A0010F92E /* UIView+FontScale.h in Headers */ = {isa = PBXBuildFile; fileRef = DACE2F6A19BA6A2A0010F92E /* UIView+FontScale.h */; }; @@ -3296,6 +3296,7 @@ DAFE4A3015039824003ABA7C /* PearlStringUtils.m in Sources */, DAFE4A3515039824003ABA7C /* PearlCryptUtils.m in Sources */, DAFE4A3715039824003ABA7C /* PearlKeyChain.m in Sources */, + DA72BD7B19C1510C00E6ACFE /* UIView+FontScale.m in Sources */, DA250A17195665A100AC23F1 /* UITableView+PearlReloadFromArray.m in Sources */, DAFE4A3915039824003ABA7C /* PearlRSAKey.m in Sources */, DAFE4A3B15039824003ABA7C /* PearlSCrypt.m in Sources */, @@ -3328,7 +3329,6 @@ DAEC85B518E3DD9A007FC0DF /* UIView+Touches.m in Sources */, DA2CA4DD18D28859007798F8 /* NSArray+Pearl.m in Sources */, DAFE4A63150399FF003ABA8A /* UIControl+PearlSelect.m in Sources */, - DACE2F6B19BA6A2A0010F92E /* UIView+FontScale.m in Sources */, DAFE4A63150399FF003ABA8E /* UIScrollView+PearlFlashingIndicators.m in Sources */, DAFE4A63150399FF003ABA92 /* NSDateFormatter+RFC3339.m in Sources */, DA2CA4E618D2AC10007798F8 /* NSLayoutConstraint+PearlUIKit.m in Sources */, diff --git a/MasterPassword/ObjC/iOS/Storyboard.storyboard b/MasterPassword/ObjC/iOS/Storyboard.storyboard index c2dd8357..ee8d6608 100644 --- a/MasterPassword/ObjC/iOS/Storyboard.storyboard +++ b/MasterPassword/ObjC/iOS/Storyboard.storyboard @@ -46,7 +46,6 @@ Exo2.0-Regular Exo2.0-Regular Exo2.0-Regular - Exo2.0-Regular Exo2.0-Thin @@ -126,10 +125,10 @@ - + -