Edit indicator, cell reuse fix and item reloading improvement.
[ADDED] Indicator when user needs to find the edit button to either set a password or login name. [FIXED] Cell reuse when changing between transient / element. [IMPROVED] Collection view item reloading now avoids reloading items that stay the same and animates better.
This commit is contained in:
parent
2aebcadf70
commit
27f6bd7905
2
External/Pearl
vendored
2
External/Pearl
vendored
@ -1 +1 @@
|
|||||||
Subproject commit a4c734e07c7441b4a49e83ae0a5de02158095ed7
|
Subproject commit 5c183fe325c7225c06910b81ac64117eb8a7aad2
|
BIN
External/iOS/Crashlytics.framework/submit
vendored
BIN
External/iOS/Crashlytics.framework/submit
vendored
Binary file not shown.
@ -35,6 +35,7 @@
|
|||||||
@property(nonatomic, strong) IBOutlet UIButton *editButton;
|
@property(nonatomic, strong) IBOutlet UIButton *editButton;
|
||||||
@property(nonatomic, strong) IBOutlet UIScrollView *modeScrollView;
|
@property(nonatomic, strong) IBOutlet UIScrollView *modeScrollView;
|
||||||
@property(nonatomic, strong) IBOutlet UIButton *selectionButton;
|
@property(nonatomic, strong) IBOutlet UIButton *selectionButton;
|
||||||
|
@property(nonatomic, strong) IBOutlet UIView *indicatorView;
|
||||||
|
|
||||||
@property(nonatomic) MPPasswordCellMode mode;
|
@property(nonatomic) MPPasswordCellMode mode;
|
||||||
@property(nonatomic, copy) NSString *transientSite;
|
@property(nonatomic, copy) NSString *transientSite;
|
||||||
@ -66,12 +67,19 @@
|
|||||||
|
|
||||||
[self.selectionButton observeKeyPath:@"highlighted"
|
[self.selectionButton observeKeyPath:@"highlighted"
|
||||||
withBlock:^(id from, id to, NSKeyValueChange cause, UIButton *button) {
|
withBlock:^(id from, id to, NSKeyValueChange cause, UIButton *button) {
|
||||||
button.layer.shadowOpacity = button.selected? 1: button.highlighted? 0.3f: 0;
|
button.layer.shadowOpacity = button.selected? 1: button.highlighted? 0.3f: 0;
|
||||||
}];
|
}];
|
||||||
[self.selectionButton observeKeyPath:@"selected"
|
[self.selectionButton observeKeyPath:@"selected"
|
||||||
withBlock:^(id from, id to, NSKeyValueChange cause, UIButton *button) {
|
withBlock:^(id from, id to, NSKeyValueChange cause, UIButton *button) {
|
||||||
button.layer.shadowOpacity = button.selected? 1: button.highlighted? 0.3f: 0;
|
button.layer.shadowOpacity = button.selected? 1: button.highlighted? 0.3f: 0;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.y"];
|
||||||
|
animation.byValue = @(10);
|
||||||
|
animation.repeatCount = HUGE_VALF;
|
||||||
|
animation.autoreverses = YES;
|
||||||
|
animation.duration = 0.3f;
|
||||||
|
[self.indicatorView.layer addAnimation:animation forKey:@"bounce"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)prepareForReuse {
|
- (void)prepareForReuse {
|
||||||
@ -79,6 +87,7 @@
|
|||||||
[super prepareForReuse];
|
[super prepareForReuse];
|
||||||
|
|
||||||
_elementOID = nil;
|
_elementOID = nil;
|
||||||
|
self.transientSite = nil;
|
||||||
self.loginModeButton.selected = NO;
|
self.loginModeButton.selected = NO;
|
||||||
self.mode = MPPasswordCellModePassword;
|
self.mode = MPPasswordCellModePassword;
|
||||||
[self updateAnimated:NO];
|
[self updateAnimated:NO];
|
||||||
@ -182,14 +191,14 @@
|
|||||||
|
|
||||||
[PearlSheet showSheetWithTitle:strf( @"Delete %@?", element.name ) viewStyle:UIActionSheetStyleAutomatic
|
[PearlSheet showSheetWithTitle:strf( @"Delete %@?", element.name ) viewStyle:UIActionSheetStyleAutomatic
|
||||||
initSheet:nil tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
|
initSheet:nil tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
|
||||||
if (buttonIndex == [sheet cancelButtonIndex])
|
if (buttonIndex == [sheet cancelButtonIndex])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
[context deleteObject:[self elementInContext:context]];
|
[context deleteObject:[self elementInContext:context]];
|
||||||
[context saveToStore];
|
[context saveToStore];
|
||||||
}];
|
}];
|
||||||
} cancelTitle:@"Cancel" destructiveTitle:@"Delete Site" otherTitles:nil];
|
} cancelTitle:@"Cancel" destructiveTitle:@"Delete Site" otherTitles:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)doChangeType:(UIButton *)sender {
|
- (IBAction)doChangeType:(UIButton *)sender {
|
||||||
@ -198,27 +207,28 @@
|
|||||||
|
|
||||||
[PearlSheet showSheetWithTitle:@"Change Password Type" viewStyle:UIActionSheetStyleAutomatic
|
[PearlSheet showSheetWithTitle:@"Change Password Type" viewStyle:UIActionSheetStyleAutomatic
|
||||||
initSheet:^(UIActionSheet *sheet) {
|
initSheet:^(UIActionSheet *sheet) {
|
||||||
MPElementEntity *mainElement = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
MPElementEntity
|
||||||
for (NSNumber *typeNumber in [MPAlgorithmDefault allTypes]) {
|
*mainElement = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
||||||
MPElementType type = [typeNumber unsignedIntegerValue];
|
for (NSNumber *typeNumber in [MPAlgorithmDefault allTypes]) {
|
||||||
NSString *typeName = [MPAlgorithmDefault nameOfType:type];
|
MPElementType type = [typeNumber unsignedIntegerValue];
|
||||||
if (type == mainElement.type)
|
NSString *typeName = [MPAlgorithmDefault nameOfType:type];
|
||||||
[sheet addButtonWithTitle:strf( @"● %@", typeName )];
|
if (type == mainElement.type)
|
||||||
else
|
[sheet addButtonWithTitle:strf( @"● %@", typeName )];
|
||||||
[sheet addButtonWithTitle:typeName];
|
else
|
||||||
}
|
[sheet addButtonWithTitle:typeName];
|
||||||
} tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
|
}
|
||||||
if (buttonIndex == [sheet cancelButtonIndex])
|
} tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
|
||||||
return;
|
if (buttonIndex == [sheet cancelButtonIndex])
|
||||||
|
return;
|
||||||
|
|
||||||
MPElementType type = [[MPAlgorithmDefault allTypes][buttonIndex] unsignedIntegerValue]?: MPElementTypeGeneratedLong;
|
MPElementType type = [[MPAlgorithmDefault allTypes][buttonIndex] unsignedIntegerValue]?: MPElementTypeGeneratedLong;
|
||||||
|
|
||||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
MPElementEntity *element = [self elementInContext:context];
|
MPElementEntity *element = [self elementInContext:context];
|
||||||
element = [[MPiOSAppDelegate get] changeElement:element saveInContext:context toType:type];
|
element = [[MPiOSAppDelegate get] changeElement:element saveInContext:context toType:type];
|
||||||
[self setElement:element animated:YES];
|
[self setElement:element animated:YES];
|
||||||
}];
|
}];
|
||||||
} cancelTitle:@"Cancel" destructiveTitle:nil otherTitles:nil];
|
} cancelTitle:@"Cancel" destructiveTitle:nil otherTitles:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)doEdit:(UIButton *)sender {
|
- (IBAction)doEdit:(UIButton *)sender {
|
||||||
@ -318,19 +328,19 @@
|
|||||||
message:strf( @"Remember site named:\n%@", self.transientSite )
|
message:strf( @"Remember site named:\n%@", self.transientSite )
|
||||||
viewStyle:UIAlertViewStyleDefault
|
viewStyle:UIAlertViewStyleDefault
|
||||||
initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
|
initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
|
||||||
if (buttonIndex == [alert cancelButtonIndex]) {
|
if (buttonIndex == [alert cancelButtonIndex]) {
|
||||||
self.selectionButton.selected = NO;
|
self.selectionButton.selected = NO;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[MPiOSAppDelegate get]
|
[[MPiOSAppDelegate get]
|
||||||
addElementNamed:self.transientSite completion:^(MPElementEntity *element, NSManagedObjectContext *context) {
|
addElementNamed:self.transientSite completion:^(MPElementEntity *element, NSManagedObjectContext *context) {
|
||||||
[self copyContentOfElement:element saveInContext:context];
|
[self copyContentOfElement:element saveInContext:context];
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
self.selectionButton.selected = NO;
|
self.selectionButton.selected = NO;
|
||||||
} );
|
} );
|
||||||
}];
|
}];
|
||||||
} cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonYes, nil];
|
} cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonYes, nil];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,13 +382,39 @@
|
|||||||
self.passwordField.alpha = self.loginModeButton.selected? 0: 1;
|
self.passwordField.alpha = self.loginModeButton.selected? 0: 1;
|
||||||
self.loginNameField.alpha = self.loginModeButton.selected? 1: 0;
|
self.loginNameField.alpha = self.loginModeButton.selected? 1: 0;
|
||||||
self.modeButton.alpha = self.transientSite? 0: 1;
|
self.modeButton.alpha = self.transientSite? 0: 1;
|
||||||
|
self.loginModeButton.alpha = self.transientSite? 0: 1;
|
||||||
self.counterLabel.alpha = self.counterButton.alpha = mainElement.type & MPElementTypeClassGenerated? 1: 0;
|
self.counterLabel.alpha = self.counterButton.alpha = mainElement.type & MPElementTypeClassGenerated? 1: 0;
|
||||||
self.modeButton.selected = self.mode == MPPasswordCellModeSettings;
|
self.modeButton.selected = self.mode == MPPasswordCellModeSettings;
|
||||||
self.pageControl.currentPage = self.mode == MPPasswordCellModePassword? 0: 1;
|
self.pageControl.currentPage = self.mode == MPPasswordCellModePassword? 0: 1;
|
||||||
self.strengthLabel.alpha = self.mode == MPPasswordCellModePassword? 0: 1;
|
self.strengthLabel.alpha = self.mode == MPPasswordCellModePassword? 0: 1;
|
||||||
self.editButton.enabled = self.loginModeButton.selected || mainElement.type & MPElementTypeClassStored;
|
self.editButton.enabled = self.loginModeButton.selected || mainElement.type & MPElementTypeClassStored;
|
||||||
|
self.modeScrollView.scrollEnabled = !self.transientSite;
|
||||||
|
self.pageControl.alpha = self.transientSite? 0: 1;
|
||||||
[self.modeScrollView setContentOffset:CGPointMake( self.mode * self.modeScrollView.frame.size.width, 0 ) animated:animated];
|
[self.modeScrollView setContentOffset:CGPointMake( self.mode * self.modeScrollView.frame.size.width, 0 ) animated:animated];
|
||||||
|
|
||||||
|
// Indicator
|
||||||
|
if (self.loginModeButton.selected) {
|
||||||
|
if ([mainElement.loginName length])
|
||||||
|
self.indicatorView.alpha = 0;
|
||||||
|
else {
|
||||||
|
self.indicatorView.alpha = 1;
|
||||||
|
[self.indicatorView removeFromSuperview];
|
||||||
|
[self.modeScrollView addSubview:self.indicatorView];
|
||||||
|
[self.contentView addConstraintsWithVisualFormat:@"V:[indicator][view]" options:NSLayoutFormatAlignAllCenterX
|
||||||
|
metrics:nil views:@{
|
||||||
|
@"indicator" : self.indicatorView,
|
||||||
|
@"view" : self.mode == MPPasswordCellModeSettings? self.editButton: self.modeButton
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (self.mode) {
|
||||||
|
case MPPasswordCellModePassword:
|
||||||
|
if (mainElement.type & MPElementTypeClassStored)
|
||||||
|
break;
|
||||||
|
case MPPasswordCellModeSettings:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Site Name
|
// Site Name
|
||||||
self.siteNameLabel.text = strl( @"%@ - %@", self.transientSite?: mainElement.name,
|
self.siteNameLabel.text = strl( @"%@ - %@", self.transientSite?: mainElement.name,
|
||||||
self.transientSite? @"Tap to create": [mainElement.algorithm shortNameOfType:mainElement.type] );
|
self.transientSite? @"Tap to create": [mainElement.algorithm shortNameOfType:mainElement.type] );
|
||||||
@ -389,13 +425,13 @@
|
|||||||
self.passwordField.attributedPlaceholder = stra(
|
self.passwordField.attributedPlaceholder = stra(
|
||||||
mainElement.type & MPElementTypeClassStored? strl( @"No password" ):
|
mainElement.type & MPElementTypeClassStored? strl( @"No password" ):
|
||||||
mainElement.type & MPElementTypeClassGenerated? strl( @"..." ): @"", @{
|
mainElement.type & MPElementTypeClassGenerated? strl( @"..." ): @"", @{
|
||||||
NSForegroundColorAttributeName : [UIColor whiteColor]
|
NSForegroundColorAttributeName : [UIColor whiteColor]
|
||||||
} );
|
} );
|
||||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
NSString *password;
|
NSString *password;
|
||||||
if (self.transientSite)
|
if (self.transientSite)
|
||||||
password = [MPAlgorithmDefault generateContentNamed:self.transientSite ofType:
|
password = [MPAlgorithmDefault generateContentNamed:self.transientSite ofType:
|
||||||
[[MPiOSAppDelegate get] activeUserInContext:context].defaultType?: MPElementTypeGeneratedLong
|
[[MPiOSAppDelegate get] activeUserInContext:context].defaultType?: MPElementTypeGeneratedLong
|
||||||
withCounter:1 usingKey:[MPiOSAppDelegate get].key];
|
withCounter:1 usingKey:[MPiOSAppDelegate get].key];
|
||||||
else
|
else
|
||||||
password = [[self elementInContext:context] resolveContentUsingKey:[MPiOSAppDelegate get].key];
|
password = [[self elementInContext:context] resolveContentUsingKey:[MPiOSAppDelegate get].key];
|
||||||
@ -411,6 +447,21 @@
|
|||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
self.passwordField.text = password;
|
self.passwordField.text = password;
|
||||||
self.strengthLabel.text = timeToCrackString;
|
self.strengthLabel.text = timeToCrackString;
|
||||||
|
|
||||||
|
if (!self.loginModeButton.selected) {
|
||||||
|
if ([password length])
|
||||||
|
self.indicatorView.alpha = 0;
|
||||||
|
else {
|
||||||
|
self.indicatorView.alpha = 1;
|
||||||
|
[self.indicatorView removeFromSuperview];
|
||||||
|
[self.modeScrollView addSubview:self.indicatorView];
|
||||||
|
[self.contentView addConstraintsWithVisualFormat:@"V:[indicator][view]" options:NSLayoutFormatAlignAllCenterX
|
||||||
|
metrics:nil views:@{
|
||||||
|
@"indicator" : self.indicatorView,
|
||||||
|
@"view" : self.mode == MPPasswordCellModeSettings? self.editButton: self.modeButton
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
} );
|
} );
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#import "MPPopdownSegue.h"
|
#import "MPPopdownSegue.h"
|
||||||
#import "MPAppDelegate_Key.h"
|
#import "MPAppDelegate_Key.h"
|
||||||
#import "MPPasswordCell.h"
|
#import "MPPasswordCell.h"
|
||||||
|
#import "UICollectionView+PearlReloadFromArray.h"
|
||||||
|
|
||||||
@interface MPPasswordsViewController()<NSFetchedResultsControllerDelegate>
|
@interface MPPasswordsViewController()<NSFetchedResultsControllerDelegate>
|
||||||
|
|
||||||
@ -36,10 +37,11 @@
|
|||||||
NSArray *_notificationObservers;
|
NSArray *_notificationObservers;
|
||||||
__weak UITapGestureRecognizer *_passwordsDismissRecognizer;
|
__weak UITapGestureRecognizer *_passwordsDismissRecognizer;
|
||||||
NSFetchedResultsController *_fetchedResultsController;
|
NSFetchedResultsController *_fetchedResultsController;
|
||||||
BOOL _exactMatch;
|
|
||||||
UIColor *_backgroundColor;
|
UIColor *_backgroundColor;
|
||||||
UIColor *_darkenedBackgroundColor;
|
UIColor *_darkenedBackgroundColor;
|
||||||
__weak UIViewController *_popdownVC;
|
__weak UIViewController *_popdownVC;
|
||||||
|
BOOL _showTransientItem;
|
||||||
|
NSUInteger _transientItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Life
|
#pragma mark - Life
|
||||||
@ -50,6 +52,7 @@
|
|||||||
|
|
||||||
_backgroundColor = self.passwordCollectionView.backgroundColor;
|
_backgroundColor = self.passwordCollectionView.backgroundColor;
|
||||||
_darkenedBackgroundColor = [_backgroundColor colorWithAlphaComponent:0.6f];
|
_darkenedBackgroundColor = [_backgroundColor colorWithAlphaComponent:0.6f];
|
||||||
|
_transientItem = NSNotFound;
|
||||||
|
|
||||||
self.view.backgroundColor = [UIColor clearColor];
|
self.view.backgroundColor = [UIColor clearColor];
|
||||||
[self.passwordCollectionView automaticallyAdjustInsetsForKeyboard];
|
[self.passwordCollectionView automaticallyAdjustInsetsForKeyboard];
|
||||||
@ -115,9 +118,12 @@ referenceSizeForHeaderInSection:(NSInteger)section {
|
|||||||
|
|
||||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||||
|
|
||||||
return ![MPiOSAppDelegate get].activeUserOID? 0:
|
if (![MPiOSAppDelegate get].activeUserOID)
|
||||||
((id<NSFetchedResultsSectionInfo>)self.fetchedResultsController.sections[section]).numberOfObjects +
|
return 0;
|
||||||
(!_exactMatch && [[self query] length]? 1: 0);
|
|
||||||
|
NSUInteger objects = ((id<NSFetchedResultsSectionInfo>)self.fetchedResultsController.sections[section]).numberOfObjects;
|
||||||
|
_transientItem = _showTransientItem? objects: NSNotFound;
|
||||||
|
return objects + (_showTransientItem? 1: 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
@ -152,20 +158,23 @@ referenceSizeForHeaderInSection:(NSInteger)section {
|
|||||||
forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
|
forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
|
||||||
|
|
||||||
if (controller == _fetchedResultsController) {
|
if (controller == _fetchedResultsController) {
|
||||||
switch (type) {
|
[self.passwordCollectionView performBatchUpdates:^{
|
||||||
case NSFetchedResultsChangeInsert:
|
[self fetchedItemsDidUpdate];
|
||||||
[self.passwordCollectionView insertItemsAtIndexPaths:@[ newIndexPath ]];
|
switch (type) {
|
||||||
break;
|
case NSFetchedResultsChangeInsert:
|
||||||
case NSFetchedResultsChangeDelete:
|
[self.passwordCollectionView insertItemsAtIndexPaths:@[ newIndexPath ]];
|
||||||
[self.passwordCollectionView deleteItemsAtIndexPaths:@[ indexPath ]];
|
break;
|
||||||
break;
|
case NSFetchedResultsChangeDelete:
|
||||||
case NSFetchedResultsChangeMove:
|
[self.passwordCollectionView deleteItemsAtIndexPaths:@[ indexPath ]];
|
||||||
[self.passwordCollectionView moveItemAtIndexPath:indexPath toIndexPath:newIndexPath];
|
break;
|
||||||
break;
|
case NSFetchedResultsChangeMove:
|
||||||
case NSFetchedResultsChangeUpdate:
|
[self.passwordCollectionView moveItemAtIndexPath:indexPath toIndexPath:newIndexPath];
|
||||||
[self.passwordCollectionView reloadItemsAtIndexPaths:@[ indexPath ]];
|
break;
|
||||||
break;
|
case NSFetchedResultsChangeUpdate:
|
||||||
}
|
[self.passwordCollectionView reloadItemsAtIndexPaths:@[ indexPath ]];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} completion:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,6 +238,33 @@ referenceSizeForHeaderInSection:(NSInteger)section {
|
|||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
|
|
||||||
|
- (void)fetchedItemsDidUpdate {
|
||||||
|
|
||||||
|
NSString *query = self.query;
|
||||||
|
_showTransientItem = [query length] > 0;
|
||||||
|
NSUInteger objects = ((id<NSFetchedResultsSectionInfo>)self.fetchedResultsController.sections[0]).numberOfObjects;
|
||||||
|
if (_showTransientItem && objects == 1 &&
|
||||||
|
[[[self.fetchedResultsController.fetchedObjects firstObject] name] isEqualToString:query])
|
||||||
|
_showTransientItem = NO;
|
||||||
|
if ([self.passwordCollectionView numberOfSections] > 0) {
|
||||||
|
if (!_showTransientItem && _transientItem != NSNotFound) {
|
||||||
|
dbg( @"delete transient item: %d", [self.passwordCollectionView numberOfItemsInSection:0] - 1 );
|
||||||
|
[self.passwordCollectionView deleteItemsAtIndexPaths:
|
||||||
|
@[ [NSIndexPath indexPathForItem:_transientItem inSection:0] ]];
|
||||||
|
}
|
||||||
|
else if (_showTransientItem && _transientItem == NSNotFound) {
|
||||||
|
dbg( @"insert transient item: %d", objects );
|
||||||
|
[self.passwordCollectionView insertItemsAtIndexPaths:
|
||||||
|
@[ [NSIndexPath indexPathForItem:objects inSection:0] ]];
|
||||||
|
}
|
||||||
|
else if (_transientItem != NSNotFound) {
|
||||||
|
dbg( @"reload transient item: %d", objects );
|
||||||
|
[self.passwordCollectionView reloadItemsAtIndexPaths:
|
||||||
|
@[ [NSIndexPath indexPathForItem:_transientItem inSection:0] ]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)registerObservers {
|
- (void)registerObservers {
|
||||||
|
|
||||||
if ([_notificationObservers count])
|
if ([_notificationObservers count])
|
||||||
@ -239,34 +275,34 @@ referenceSizeForHeaderInSection:(NSInteger)section {
|
|||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
addObserverForName:UIApplicationWillResignActiveNotification object:nil
|
addObserverForName:UIApplicationWillResignActiveNotification object:nil
|
||||||
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||||
Strongify( self );
|
Strongify( self );
|
||||||
|
|
||||||
self.passwordSelectionContainer.alpha = 0;
|
self.passwordSelectionContainer.alpha = 0;
|
||||||
}],
|
}],
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
addObserverForName:MPSignedOutNotification object:nil
|
addObserverForName:MPSignedOutNotification object:nil
|
||||||
queue:nil usingBlock:^(NSNotification *note) {
|
queue:nil usingBlock:^(NSNotification *note) {
|
||||||
Strongify( self );
|
Strongify( self );
|
||||||
|
|
||||||
_fetchedResultsController = nil;
|
_fetchedResultsController = nil;
|
||||||
self.passwordsSearchBar.text = nil;
|
self.passwordsSearchBar.text = nil;
|
||||||
[self updatePasswords];
|
[self updatePasswords];
|
||||||
}],
|
}],
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
addObserverForName:UIApplicationDidBecomeActiveNotification object:nil
|
addObserverForName:UIApplicationDidBecomeActiveNotification object:nil
|
||||||
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||||
Strongify( self );
|
Strongify( self );
|
||||||
|
|
||||||
[self updatePasswords];
|
[self updatePasswords];
|
||||||
[UIView animateWithDuration:1 animations:^{
|
[UIView animateWithDuration:1 animations:^{
|
||||||
self.passwordSelectionContainer.alpha = 1;
|
self.passwordSelectionContainer.alpha = 1;
|
||||||
}];
|
}];
|
||||||
}],
|
}],
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
addObserverForName:MPCheckConfigNotification object:nil queue:[NSOperationQueue mainQueue]
|
addObserverForName:MPCheckConfigNotification object:nil queue:[NSOperationQueue mainQueue]
|
||||||
usingBlock:^(NSNotification *note) {
|
usingBlock:^(NSNotification *note) {
|
||||||
[self updateConfigKey:note.object];
|
[self updateConfigKey:note.object];
|
||||||
}],
|
}],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +365,8 @@ referenceSizeForHeaderInSection:(NSInteger)section {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[self.fetchedResultsController.managedObjectContext performBlock:^{
|
[self.fetchedResultsController.managedObjectContext performBlock:^{
|
||||||
|
NSArray *oldSections = [self.fetchedResultsController sections];
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
self.fetchedResultsController.fetchRequest.predicate =
|
self.fetchedResultsController.fetchRequest.predicate =
|
||||||
[query length]?
|
[query length]?
|
||||||
@ -337,37 +375,32 @@ referenceSizeForHeaderInSection:(NSInteger)section {
|
|||||||
if (![self.fetchedResultsController performFetch:&error])
|
if (![self.fetchedResultsController performFetch:&error])
|
||||||
err( @"Couldn't fetch elements: %@", error );
|
err( @"Couldn't fetch elements: %@", error );
|
||||||
|
|
||||||
_exactMatch = NO;
|
[self.passwordCollectionView performBatchUpdates:^{
|
||||||
for (MPElementEntity *entity in self.fetchedResultsController.fetchedObjects)
|
[self fetchedItemsDidUpdate];
|
||||||
if ([entity.name isEqualToString:query]) {
|
|
||||||
_exactMatch = YES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PearlMainQueue( ^{
|
NSInteger fromSections = self.passwordCollectionView.numberOfSections;
|
||||||
[self.passwordCollectionView performBatchUpdates:^{
|
NSInteger toSections = [self numberOfSectionsInCollectionView:self.passwordCollectionView];
|
||||||
NSInteger fromSections = self.passwordCollectionView.numberOfSections;
|
for (NSInteger section = 0; section < MAX( toSections, fromSections ); ++section) {
|
||||||
NSInteger toSections = [self numberOfSectionsInCollectionView:self.passwordCollectionView];
|
if (section >= fromSections) {
|
||||||
for (int section = 0; section < MAX( toSections, fromSections ); section++) {
|
dbg( @"insertSections:%d", section );
|
||||||
if (section >= fromSections) {
|
[self.passwordCollectionView insertSections:[NSIndexSet indexSetWithIndex:section]];
|
||||||
dbg( @"insertSections:%d", section );
|
|
||||||
[self.passwordCollectionView insertSections:[NSIndexSet indexSetWithIndex:section]];
|
|
||||||
}
|
|
||||||
else if (section >= toSections) {
|
|
||||||
dbg( @"deleteSections:%d", section );
|
|
||||||
[self.passwordCollectionView deleteSections:[NSIndexSet indexSetWithIndex:section]];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dbg( @"reloadSections:%d", section );
|
|
||||||
[self.passwordCollectionView reloadSections:[NSIndexSet indexSetWithIndex:section]];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} completion:^(BOOL finished) {
|
else if (section >= toSections) {
|
||||||
if (finished)
|
dbg( @"deleteSections:%d", section );
|
||||||
[self.passwordCollectionView setContentOffset:CGPointMake( 0, -self.passwordCollectionView.contentInset.top )
|
[self.passwordCollectionView deleteSections:[NSIndexSet indexSetWithIndex:section]];
|
||||||
animated:YES];
|
}
|
||||||
}];
|
else {
|
||||||
} );
|
dbg( @"reloadItemsInSection:%d", section );
|
||||||
|
[self.passwordCollectionView reloadItemsFromArray:[oldSections[section] objects]
|
||||||
|
toArray:[[self.fetchedResultsController sections][section] objects]
|
||||||
|
inSection:section];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
if (finished)
|
||||||
|
[self.passwordCollectionView setContentOffset:CGPointMake( 0, -self.passwordCollectionView.contentInset.top )
|
||||||
|
animated:YES];
|
||||||
|
}];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
93D3992FA1546E01F498F665 /* PearlNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D398567FD02DB2647B8CF3 /* PearlNavigationController.h */; };
|
93D3992FA1546E01F498F665 /* PearlNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D398567FD02DB2647B8CF3 /* PearlNavigationController.h */; };
|
||||||
93D399433EA75E50656040CB /* Twitter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93D394077F8FAB8167647187 /* Twitter.framework */; };
|
93D399433EA75E50656040CB /* Twitter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93D394077F8FAB8167647187 /* Twitter.framework */; };
|
||||||
93D399BBC0A7EC746CB1B19B /* MPLogsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D391943675426839501BB8 /* MPLogsViewController.h */; };
|
93D399BBC0A7EC746CB1B19B /* MPLogsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D391943675426839501BB8 /* MPLogsViewController.h */; };
|
||||||
|
93D39A53D76CA70786423458 /* UICollectionView+PearlReloadFromArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadFromArray.h */; };
|
||||||
93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DEA995041A13DC9CAF7 /* MPPasswordCell.m */; };
|
93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DEA995041A13DC9CAF7 /* MPPasswordCell.m */; };
|
||||||
93D39A8EA1C49CE43B63F47B /* PearlUICollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D8A953779B35403AF6E /* PearlUICollectionView.m */; };
|
93D39A8EA1C49CE43B63F47B /* PearlUICollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D8A953779B35403AF6E /* PearlUICollectionView.m */; };
|
||||||
93D39B76DD5AB108BA8928E8 /* UIScrollView+PearlAdjustInsets.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39DE2CB351D4E3789462B /* UIScrollView+PearlAdjustInsets.h */; };
|
93D39B76DD5AB108BA8928E8 /* UIScrollView+PearlAdjustInsets.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39DE2CB351D4E3789462B /* UIScrollView+PearlAdjustInsets.h */; };
|
||||||
@ -41,6 +42,7 @@
|
|||||||
93D39B8F90F58A5D158DDBA3 /* MPPasswordsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3924EE15017F8A12CB436 /* MPPasswordsViewController.m */; };
|
93D39B8F90F58A5D158DDBA3 /* MPPasswordsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3924EE15017F8A12CB436 /* MPPasswordsViewController.m */; };
|
||||||
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3916C1D8F1427DFBDEBCA /* MPAppSettingsViewController.m */; };
|
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3916C1D8F1427DFBDEBCA /* MPAppSettingsViewController.m */; };
|
||||||
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
|
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
|
||||||
|
93D39D47FC623E91FC39D20C /* UICollectionView+PearlReloadFromArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */; };
|
||||||
93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393310223DDB35218467A /* MPCombinedViewController.m */; };
|
93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393310223DDB35218467A /* MPCombinedViewController.m */; };
|
||||||
93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39CC01630D0421205C4C4 /* MPNavigationController.m */; };
|
93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39CC01630D0421205C4C4 /* MPNavigationController.m */; };
|
||||||
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; };
|
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; };
|
||||||
@ -381,12 +383,14 @@
|
|||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
93D390519405B76CC6A57C4F /* MPCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCell.h; sourceTree = "<group>"; };
|
93D390519405B76CC6A57C4F /* MPCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCell.h; sourceTree = "<group>"; };
|
||||||
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
||||||
|
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionView+PearlReloadFromArray.m"; sourceTree = "<group>"; };
|
||||||
93D390FADEB325D8D54A957D /* PearlOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlOverlay.m; sourceTree = "<group>"; };
|
93D390FADEB325D8D54A957D /* PearlOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlOverlay.m; sourceTree = "<group>"; };
|
||||||
93D390FB3110DCCE68E600DC /* UIScrollView+PearlAdjustInsets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+PearlAdjustInsets.m"; sourceTree = "<group>"; };
|
93D390FB3110DCCE68E600DC /* UIScrollView+PearlAdjustInsets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+PearlAdjustInsets.m"; sourceTree = "<group>"; };
|
||||||
93D3914D7597F9A28DB9D85E /* MPPasswordsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordsViewController.h; sourceTree = "<group>"; };
|
93D3914D7597F9A28DB9D85E /* MPPasswordsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordsViewController.h; sourceTree = "<group>"; };
|
||||||
93D39156E806BB78E04F78B9 /* PearlSizedTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlSizedTextView.m; sourceTree = "<group>"; };
|
93D39156E806BB78E04F78B9 /* PearlSizedTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlSizedTextView.m; sourceTree = "<group>"; };
|
||||||
93D3916C1D8F1427DFBDEBCA /* MPAppSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppSettingsViewController.m; sourceTree = "<group>"; };
|
93D3916C1D8F1427DFBDEBCA /* MPAppSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppSettingsViewController.m; sourceTree = "<group>"; };
|
||||||
93D391943675426839501BB8 /* MPLogsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPLogsViewController.h; sourceTree = "<group>"; };
|
93D391943675426839501BB8 /* MPLogsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPLogsViewController.h; sourceTree = "<group>"; };
|
||||||
|
93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadFromArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionView+PearlReloadFromArray.h"; sourceTree = "<group>"; };
|
||||||
93D3924EE15017F8A12CB436 /* MPPasswordsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordsViewController.m; sourceTree = "<group>"; };
|
93D3924EE15017F8A12CB436 /* MPPasswordsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordsViewController.m; sourceTree = "<group>"; };
|
||||||
93D392876BE5C011DE73B43F /* MPPopdownSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPopdownSegue.h; sourceTree = "<group>"; };
|
93D392876BE5C011DE73B43F /* MPPopdownSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPopdownSegue.h; sourceTree = "<group>"; };
|
||||||
93D393310223DDB35218467A /* MPCombinedViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCombinedViewController.m; sourceTree = "<group>"; };
|
93D393310223DDB35218467A /* MPCombinedViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCombinedViewController.m; sourceTree = "<group>"; };
|
||||||
@ -2628,6 +2632,8 @@
|
|||||||
93D39A4759186F6D2D34AA6B /* PearlSizedTextView.h */,
|
93D39A4759186F6D2D34AA6B /* PearlSizedTextView.h */,
|
||||||
93D3977321EB249981821AB0 /* UITextView+PearlAttributes.m */,
|
93D3977321EB249981821AB0 /* UITextView+PearlAttributes.m */,
|
||||||
93D39AA10CD00D05937671B1 /* UITextView+PearlAttributes.h */,
|
93D39AA10CD00D05937671B1 /* UITextView+PearlAttributes.h */,
|
||||||
|
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */,
|
||||||
|
93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadFromArray.h */,
|
||||||
);
|
);
|
||||||
path = "Pearl-UIKit";
|
path = "Pearl-UIKit";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2741,6 +2747,7 @@
|
|||||||
93D39536EB550E811CCD04BC /* UIResponder+PearlFirstResponder.h in Headers */,
|
93D39536EB550E811CCD04BC /* UIResponder+PearlFirstResponder.h in Headers */,
|
||||||
93D393DB5325820241BA90A7 /* PearlSizedTextView.h in Headers */,
|
93D393DB5325820241BA90A7 /* PearlSizedTextView.h in Headers */,
|
||||||
93D392A8777DC30C11361647 /* UITextView+PearlAttributes.h in Headers */,
|
93D392A8777DC30C11361647 /* UITextView+PearlAttributes.h in Headers */,
|
||||||
|
93D39A53D76CA70786423458 /* UICollectionView+PearlReloadFromArray.h in Headers */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -3308,6 +3315,7 @@
|
|||||||
DAA141201922FF020032B392 /* PearlTween.m in Sources */,
|
DAA141201922FF020032B392 /* PearlTween.m in Sources */,
|
||||||
93D391ECBD9BD2C64115B5DD /* PearlSizedTextView.m in Sources */,
|
93D391ECBD9BD2C64115B5DD /* PearlSizedTextView.m in Sources */,
|
||||||
93D39E34FD28D24FE3442C48 /* UITextView+PearlAttributes.m in Sources */,
|
93D39E34FD28D24FE3442C48 /* UITextView+PearlAttributes.m in Sources */,
|
||||||
|
93D39D47FC623E91FC39D20C /* UICollectionView+PearlReloadFromArray.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
isEnabled = "YES">
|
isEnabled = "YES">
|
||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
<CommandLineArgument
|
<CommandLineArgument
|
||||||
argument = "3"
|
argument = "0"
|
||||||
isEnabled = "YES">
|
isEnabled = "YES">
|
||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
</CommandLineArguments>
|
</CommandLineArguments>
|
||||||
|
@ -1262,6 +1262,13 @@
|
|||||||
<action selector="doMode:" destination="W2g-yv-V3V" eventType="touchUpInside" id="72U-sh-nce"/>
|
<action selector="doMode:" destination="W2g-yv-V3V" eventType="touchUpInside" id="72U-sh-nce"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.0" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="⬇︎" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tuh-Au-J9k">
|
||||||
|
<rect key="frame" x="270" y="35" width="17" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
<pageControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" numberOfPages="2" translatesAutoresizingMaskIntoConstraints="NO" id="5SS-x0-icl">
|
<pageControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" numberOfPages="2" translatesAutoresizingMaskIntoConstraints="NO" id="5SS-x0-icl">
|
||||||
<rect key="frame" x="138" y="77" width="23" height="37"/>
|
<rect key="frame" x="138" y="77" width="23" height="37"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
@ -1273,6 +1280,7 @@
|
|||||||
<constraint firstAttribute="bottom" secondItem="tl3-hd-x35" secondAttribute="bottom" id="2x2-iA-utK"/>
|
<constraint firstAttribute="bottom" secondItem="tl3-hd-x35" secondAttribute="bottom" id="2x2-iA-utK"/>
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="I0v-ou-hDb" secondAttribute="centerY" id="KPv-e0-uR0"/>
|
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="I0v-ou-hDb" secondAttribute="centerY" id="KPv-e0-uR0"/>
|
||||||
<constraint firstItem="LvK-28-fbm" firstAttribute="leading" secondItem="tl3-hd-x35" secondAttribute="trailing" id="NXL-Fd-whf"/>
|
<constraint firstItem="LvK-28-fbm" firstAttribute="leading" secondItem="tl3-hd-x35" secondAttribute="trailing" id="NXL-Fd-whf"/>
|
||||||
|
<constraint firstItem="b5f-wN-2xb" firstAttribute="top" secondItem="tuh-Au-J9k" secondAttribute="bottom" id="SBC-kJ-Gku"/>
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="Agd-0J-z5o" secondAttribute="centerY" id="W01-oa-2rY"/>
|
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="Agd-0J-z5o" secondAttribute="centerY" id="W01-oa-2rY"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="LvK-28-fbm" secondAttribute="bottom" id="ZBx-Lf-XHF"/>
|
<constraint firstAttribute="bottom" secondItem="LvK-28-fbm" secondAttribute="bottom" id="ZBx-Lf-XHF"/>
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="vGk-t6-hZn" secondAttribute="centerY" id="fGB-8g-u5b"/>
|
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="vGk-t6-hZn" secondAttribute="centerY" id="fGB-8g-u5b"/>
|
||||||
@ -1280,6 +1288,7 @@
|
|||||||
<constraint firstItem="tl3-hd-x35" firstAttribute="top" secondItem="bff-RU-OcY" secondAttribute="top" id="jc9-39-FY3"/>
|
<constraint firstItem="tl3-hd-x35" firstAttribute="top" secondItem="bff-RU-OcY" secondAttribute="top" id="jc9-39-FY3"/>
|
||||||
<constraint firstItem="OwP-sb-Wxl" firstAttribute="centerY" secondItem="b5f-wN-2xb" secondAttribute="centerY" id="m22-uE-sVm"/>
|
<constraint firstItem="OwP-sb-Wxl" firstAttribute="centerY" secondItem="b5f-wN-2xb" secondAttribute="centerY" id="m22-uE-sVm"/>
|
||||||
<constraint firstItem="K8q-bM-tzh" firstAttribute="centerY" secondItem="b5f-wN-2xb" secondAttribute="centerY" id="ofO-r3-bjz"/>
|
<constraint firstItem="K8q-bM-tzh" firstAttribute="centerY" secondItem="b5f-wN-2xb" secondAttribute="centerY" id="ofO-r3-bjz"/>
|
||||||
|
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerX" secondItem="tuh-Au-J9k" secondAttribute="centerX" id="pYG-bz-kd8"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="LvK-28-fbm" secondAttribute="trailing" id="r9d-ym-Frs"/>
|
<constraint firstAttribute="trailing" secondItem="LvK-28-fbm" secondAttribute="trailing" id="r9d-ym-Frs"/>
|
||||||
<constraint firstItem="LvK-28-fbm" firstAttribute="top" secondItem="bff-RU-OcY" secondAttribute="top" id="uqb-hB-Iq8"/>
|
<constraint firstItem="LvK-28-fbm" firstAttribute="top" secondItem="bff-RU-OcY" secondAttribute="top" id="uqb-hB-Iq8"/>
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="uZi-FT-Fe8" secondAttribute="centerY" id="xz2-kK-B4g"/>
|
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="uZi-FT-Fe8" secondAttribute="centerY" id="xz2-kK-B4g"/>
|
||||||
@ -1337,6 +1346,7 @@
|
|||||||
<outlet property="counterButton" destination="uZi-FT-Fe8" id="oaF-bB-Sgc"/>
|
<outlet property="counterButton" destination="uZi-FT-Fe8" id="oaF-bB-Sgc"/>
|
||||||
<outlet property="counterLabel" destination="PKP-M9-T8E" id="m9u-Qx-Z9N"/>
|
<outlet property="counterLabel" destination="PKP-M9-T8E" id="m9u-Qx-Z9N"/>
|
||||||
<outlet property="editButton" destination="qBo-Kw-vN9" id="g0S-0o-e3D"/>
|
<outlet property="editButton" destination="qBo-Kw-vN9" id="g0S-0o-e3D"/>
|
||||||
|
<outlet property="indicatorView" destination="tuh-Au-J9k" id="K2E-de-G5P"/>
|
||||||
<outlet property="loginModeButton" destination="Agd-0J-z5o" id="VQI-nl-5Yh"/>
|
<outlet property="loginModeButton" destination="Agd-0J-z5o" id="VQI-nl-5Yh"/>
|
||||||
<outlet property="loginNameField" destination="3I9-vf-IZK" id="jK4-LI-4ST"/>
|
<outlet property="loginNameField" destination="3I9-vf-IZK" id="jK4-LI-4ST"/>
|
||||||
<outlet property="modeButton" destination="b5f-wN-2xb" id="m2X-BZ-Lbv"/>
|
<outlet property="modeButton" destination="b5f-wN-2xb" id="m2X-BZ-Lbv"/>
|
||||||
@ -2439,6 +2449,6 @@ See </string>
|
|||||||
</simulatedMetricsContainer>
|
</simulatedMetricsContainer>
|
||||||
<inferredMetricsTieBreakers>
|
<inferredMetricsTieBreakers>
|
||||||
<segue reference="GZk-I4-JyH"/>
|
<segue reference="GZk-I4-JyH"/>
|
||||||
<segue reference="k2G-nL-x3l"/>
|
<segue reference="Ql4-wf-T8u"/>
|
||||||
</inferredMetricsTieBreakers>
|
</inferredMetricsTieBreakers>
|
||||||
</document>
|
</document>
|
||||||
|
Loading…
Reference in New Issue
Block a user