New passwords display in collection view.
This commit is contained in:
parent
d036b43d6f
commit
4c8bed2826
@ -16,6 +16,7 @@
|
||||
#endif
|
||||
|
||||
@property(strong, nonatomic) MPKey *key;
|
||||
@property(strong, nonatomic) NSManagedObjectID *activeUserOID;
|
||||
|
||||
+ (instancetype)get;
|
||||
|
||||
|
@ -10,9 +10,7 @@
|
||||
#import "MPAppDelegate_Store.h"
|
||||
#import "MPAppDelegate_Key.h"
|
||||
|
||||
@implementation MPAppDelegate_Shared {
|
||||
NSManagedObjectID *_activeUserOID;
|
||||
}
|
||||
@implementation MPAppDelegate_Shared
|
||||
|
||||
+ (MPAppDelegate_Shared *)get {
|
||||
|
||||
@ -32,11 +30,11 @@
|
||||
|
||||
- (MPUserEntity *)activeUserInContext:(NSManagedObjectContext *)moc {
|
||||
|
||||
if (!_activeUserOID || !moc)
|
||||
if (!self.activeUserOID || !moc)
|
||||
return nil;
|
||||
|
||||
NSError *error;
|
||||
MPUserEntity *activeUser = (MPUserEntity *)[moc existingObjectWithID:_activeUserOID error:&error];
|
||||
MPUserEntity *activeUser = (MPUserEntity *)[moc existingObjectWithID:self.activeUserOID error:&error];
|
||||
if (!activeUser) {
|
||||
[self signOutAnimated:YES];
|
||||
err(@"Failed to retrieve active user: %@", error);
|
||||
@ -51,7 +49,7 @@
|
||||
if (activeUser.objectID.isTemporaryID && ![activeUser.managedObjectContext obtainPermanentIDsForObjects:@[ activeUser ] error:&error])
|
||||
err(@"Failed to obtain a permanent object ID after setting active user: %@", error);
|
||||
|
||||
_activeUserOID = activeUser.objectID;
|
||||
self.activeUserOID = activeUser.objectID;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -21,6 +21,8 @@ typedef enum {
|
||||
@interface MPAppDelegate_Shared(Store)<UbiquityStoreManagerDelegate>
|
||||
|
||||
+ (NSManagedObjectContext *)managedObjectContextForMainThreadIfReady;
|
||||
+ (BOOL)managedObjectContextForMainThreadPerformBlock:(void (^)(NSManagedObjectContext *mainContext))mocBlock;
|
||||
+ (BOOL)managedObjectContextForMainThreadPerformBlockAndWait:(void (^)(NSManagedObjectContext *mainContext))mocBlock;
|
||||
+ (BOOL)managedObjectContextPerformBlock:(void (^)(NSManagedObjectContext *context))mocBlock;
|
||||
+ (BOOL)managedObjectContextPerformBlockAndWait:(void (^)(NSManagedObjectContext *context))mocBlock;
|
||||
|
||||
|
@ -48,6 +48,32 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
|
||||
return mainManagedObjectContext;
|
||||
}
|
||||
|
||||
+ (BOOL)managedObjectContextForMainThreadPerformBlock:(void (^)(NSManagedObjectContext *mainContext))mocBlock {
|
||||
|
||||
NSManagedObjectContext *mainManagedObjectContext = [self managedObjectContextForMainThreadIfReady];
|
||||
if (!mainManagedObjectContext)
|
||||
return NO;
|
||||
|
||||
[mainManagedObjectContext performBlock:^{
|
||||
mocBlock( mainManagedObjectContext );
|
||||
}];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL)managedObjectContextForMainThreadPerformBlockAndWait:(void (^)(NSManagedObjectContext *mainContext))mocBlock {
|
||||
|
||||
NSManagedObjectContext *mainManagedObjectContext = [self managedObjectContextForMainThreadIfReady];
|
||||
if (!mainManagedObjectContext)
|
||||
return NO;
|
||||
|
||||
[mainManagedObjectContext performBlockAndWait:^{
|
||||
mocBlock( mainManagedObjectContext );
|
||||
}];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL)managedObjectContextPerformBlock:(void (^)(NSManagedObjectContext *context))mocBlock {
|
||||
|
||||
NSManagedObjectContext *mainManagedObjectContext = [[self get] mainManagedObjectContextIfReady];
|
||||
|
@ -35,6 +35,8 @@
|
||||
|
||||
- (NSUInteger)use;
|
||||
- (BOOL)migrateExplicitly:(BOOL)explicit;
|
||||
- (NSString *)resolveContentUsingKey:(MPKey *)key;
|
||||
- (void)resolveContentUsingKey:(MPKey *)key result:(void (^)(NSString *))result;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -145,6 +145,16 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)resolveContentUsingKey:(MPKey *)key {
|
||||
|
||||
return [self.algorithm resolveContentForElement:self usingKey:key];
|
||||
}
|
||||
|
||||
- (void)resolveContentUsingKey:(MPKey *)key result:(void (^)(NSString *))result {
|
||||
|
||||
[self.algorithm resolveContentForElement:self usingKey:key result:result];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPElementGeneratedEntity(MP)
|
||||
|
@ -37,7 +37,7 @@ const long MPAvatarAdd = 10000;
|
||||
|
||||
+ (NSString *)reuseIdentifier {
|
||||
|
||||
return @"MPAvatarCell";
|
||||
return NSStringFromClass( self );
|
||||
}
|
||||
|
||||
#pragma mark - Life cycle
|
||||
|
36
MasterPassword/ObjC/iOS/MPPasswordCell.h
Normal file
36
MasterPassword/ObjC/iOS/MPPasswordCell.h
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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 <lhunath@lyndir.com>
|
||||
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
*/
|
||||
|
||||
//
|
||||
// MPAvatarCell.h
|
||||
// MPAvatarCell
|
||||
//
|
||||
// Created by lhunath on 2014-03-11.
|
||||
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MPEntities.h"
|
||||
|
||||
@interface MPPasswordCell : UICollectionViewCell <UITextFieldDelegate>
|
||||
|
||||
@property(nonatomic, copy) NSString *transientSite;
|
||||
@property(strong, nonatomic) IBOutlet UITextField *contentField;
|
||||
|
||||
+ (NSString *)reuseIdentifier;
|
||||
|
||||
- (MPElementEntity *)elementInContext:(NSManagedObjectContext *)context;
|
||||
+ (NSString *)reuseIdentifierForElement:(MPElementEntity *)entity;
|
||||
- (void)setElement:(MPElementEntity *)element;
|
||||
|
||||
- (void)updateAnimated:(BOOL)animated;
|
||||
- (void)populateWithElement:(MPElementEntity *)element;
|
||||
|
||||
@end
|
186
MasterPassword/ObjC/iOS/MPPasswordCell.m
Normal file
186
MasterPassword/ObjC/iOS/MPPasswordCell.m
Normal file
@ -0,0 +1,186 @@
|
||||
/**
|
||||
* 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 <lhunath@lyndir.com>
|
||||
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
*/
|
||||
|
||||
//
|
||||
// MPAvatarCell.h
|
||||
// MPAvatarCell
|
||||
//
|
||||
// Created by lhunath on 2014-03-11.
|
||||
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPPasswordCell.h"
|
||||
#import "MPiOSAppDelegate.h"
|
||||
#import "MPAppDelegate_Store.h"
|
||||
#import "MPPasswordGeneratedCell.h"
|
||||
#import "MPPasswordStoredCell.h"
|
||||
|
||||
@interface MPPasswordCell()
|
||||
|
||||
@property(strong, nonatomic) IBOutlet UILabel *nameLabel;
|
||||
@property(strong, nonatomic) IBOutlet UIButton *loginButton;
|
||||
|
||||
@property(nonatomic, strong) NSManagedObjectID *elementOID;
|
||||
@end
|
||||
|
||||
@implementation MPPasswordCell
|
||||
|
||||
+ (NSString *)reuseIdentifier {
|
||||
|
||||
return NSStringFromClass( self );
|
||||
}
|
||||
|
||||
+ (NSString *)reuseIdentifierForElement:(MPElementEntity *)element {
|
||||
|
||||
if ([element isKindOfClass:[MPElementGeneratedEntity class]])
|
||||
return [MPPasswordGeneratedCell reuseIdentifier];
|
||||
|
||||
if ([element isKindOfClass:[MPElementStoredEntity class]])
|
||||
return [MPPasswordStoredCell reuseIdentifier];
|
||||
|
||||
return [self reuseIdentifier];
|
||||
}
|
||||
|
||||
#pragma mark - UITextFieldDelegate
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
|
||||
|
||||
if (textField == self.contentField && [self.contentField.text length]) {
|
||||
[self.contentField resignFirstResponder];
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - Life cycle
|
||||
|
||||
- (void)awakeFromNib {
|
||||
|
||||
[super awakeFromNib];
|
||||
|
||||
self.layer.cornerRadius = 5;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
|
||||
[self removeKeyPathObservers];
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)doUser:(id)sender {
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setTransientSite:(NSString *)name {
|
||||
|
||||
_transientSite = name;
|
||||
_elementOID = nil;
|
||||
|
||||
[self updateAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)setElement:(MPElementEntity *)element {
|
||||
|
||||
self.elementOID = [element objectID];
|
||||
}
|
||||
|
||||
- (void)setElementOID:(NSManagedObjectID *)elementOID {
|
||||
|
||||
_transientSite = nil;
|
||||
_elementOID = elementOID;
|
||||
|
||||
[self updateAnimated:YES];
|
||||
}
|
||||
|
||||
- (MPElementEntity *)elementInContext:(NSManagedObjectContext *)context {
|
||||
|
||||
NSError *error = nil;
|
||||
MPElementEntity *element = _elementOID? (MPElementEntity *)[context existingObjectWithID:_elementOID error:&error]: nil;
|
||||
if (_elementOID && !element)
|
||||
err(@"Failed to load element: %@", error);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)updateAnimated:(BOOL)animated {
|
||||
|
||||
Weakify(self);
|
||||
|
||||
if (self.transientSite) {
|
||||
self.alpha = 1;
|
||||
self.nameLabel.text = self.transientSite;
|
||||
self.contentField.text = nil;
|
||||
|
||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||
MPKey *key = [MPiOSAppDelegate get].key;
|
||||
if (!key) {
|
||||
self.alpha = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
MPElementType type = [[MPiOSAppDelegate get] activeUserInContext:context].defaultType;
|
||||
if (!type)
|
||||
type = MPElementTypeGeneratedLong;
|
||||
NSString *newContent = [MPAlgorithmDefault generateContentNamed:self.transientSite ofType:type withCounter:1 usingKey:key];
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
self.contentField.text = newContent;
|
||||
}];
|
||||
}];
|
||||
}
|
||||
else if (self.elementOID) {
|
||||
NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady];
|
||||
[mainContext performBlock:^{
|
||||
[UIView animateWithDuration:animated? 0.3f: 0 animations:^{
|
||||
Strongify(self);
|
||||
NSError *error = nil;
|
||||
MPKey *key = [MPiOSAppDelegate get].key;
|
||||
if (!key) {
|
||||
self.alpha = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
MPElementEntity *element = (MPElementEntity *)[mainContext existingObjectWithID:_elementOID error:&error];
|
||||
if (!element) {
|
||||
err(@"Failed to load element: %@", error);
|
||||
self.alpha = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
self.alpha = 1;
|
||||
[self populateWithElement:element];
|
||||
|
||||
[element resolveContentUsingKey:key result:^(NSString *result) {
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
Strongify(self);
|
||||
self.contentField.text = result;
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
else {
|
||||
[UIView animateWithDuration:animated? 0.3f: 0 animations:^{
|
||||
self.alpha = 0;
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)populateWithElement:(MPElementEntity *)element {
|
||||
|
||||
self.nameLabel.text = element.name;
|
||||
self.contentField.text = nil;
|
||||
}
|
||||
|
||||
@end
|
26
MasterPassword/ObjC/iOS/MPPasswordGeneratedCell.h
Normal file
26
MasterPassword/ObjC/iOS/MPPasswordGeneratedCell.h
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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 <lhunath@lyndir.com>
|
||||
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
*/
|
||||
|
||||
//
|
||||
// MPPasswordGeneratedCell.h
|
||||
// MPPasswordGeneratedCell
|
||||
//
|
||||
// Created by lhunath on 2014-03-19.
|
||||
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MPPasswordCell.h"
|
||||
|
||||
@interface MPPasswordGeneratedCell : MPPasswordCell
|
||||
|
||||
- (MPElementGeneratedEntity *)elementInContext:(NSManagedObjectContext *)context;
|
||||
|
||||
@end
|
87
MasterPassword/ObjC/iOS/MPPasswordGeneratedCell.m
Normal file
87
MasterPassword/ObjC/iOS/MPPasswordGeneratedCell.m
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* 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 <lhunath@lyndir.com>
|
||||
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
*/
|
||||
|
||||
//
|
||||
// MPPasswordGeneratedCell.h
|
||||
// MPPasswordGeneratedCell
|
||||
//
|
||||
// Created by lhunath on 2014-03-19.
|
||||
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPPasswordGeneratedCell.h"
|
||||
#import "MPiOSAppDelegate.h"
|
||||
#import "MPAppDelegate_Store.h"
|
||||
|
||||
@interface MPPasswordGeneratedCell()
|
||||
|
||||
@property(strong, nonatomic) IBOutlet UILabel *counterLabel;
|
||||
@property(strong, nonatomic) IBOutlet UIButton *counterButton;
|
||||
@property(strong, nonatomic) IBOutlet UIButton *upgradeButton;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPPasswordGeneratedCell
|
||||
|
||||
- (void)populateWithElement:(MPElementEntity *)element {
|
||||
|
||||
[super populateWithElement:element];
|
||||
|
||||
MPElementGeneratedEntity *generatedElement = [self generatedElement:element];
|
||||
self.counterLabel.text = strf(@"%lu", (unsigned long)generatedElement.counter);
|
||||
|
||||
if (element.requiresExplicitMigration) {
|
||||
self.upgradeButton.alpha = 1;
|
||||
self.counterButton.alpha = 0;
|
||||
} else {
|
||||
self.upgradeButton.alpha = 0;
|
||||
self.counterButton.alpha = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)doUpgrade:(UIButton *)sender {
|
||||
|
||||
[MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *mainContext) {
|
||||
[[self elementInContext:mainContext] migrateExplicitly:YES];
|
||||
[mainContext saveToStore];
|
||||
|
||||
[self updateAnimated:YES];
|
||||
}];
|
||||
}
|
||||
|
||||
- (IBAction)doIncrementCounter:(UIButton *)sender {
|
||||
|
||||
[MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *mainContext) {
|
||||
++[self elementInContext:mainContext].counter;
|
||||
[mainContext saveToStore];
|
||||
|
||||
[self updateAnimated:YES];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (MPElementGeneratedEntity *)elementInContext:(NSManagedObjectContext *)context {
|
||||
|
||||
return [self generatedElement:[super elementInContext:context]];
|
||||
}
|
||||
|
||||
- (MPElementGeneratedEntity *)generatedElement:(MPElementEntity *)element {
|
||||
|
||||
NSAssert([element isKindOfClass:[MPElementGeneratedEntity class]], @"Element is not of generated type: %@", element.name);
|
||||
if (![element isKindOfClass:[MPElementGeneratedEntity class]])
|
||||
return nil;
|
||||
|
||||
return (MPElementGeneratedEntity *)element;
|
||||
}
|
||||
|
||||
@end
|
26
MasterPassword/ObjC/iOS/MPPasswordStoredCell.h
Normal file
26
MasterPassword/ObjC/iOS/MPPasswordStoredCell.h
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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 <lhunath@lyndir.com>
|
||||
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
*/
|
||||
|
||||
//
|
||||
// MPPasswordStoredCell.h
|
||||
// MPPasswordStoredCell
|
||||
//
|
||||
// Created by lhunath on 2014-03-19.
|
||||
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MPPasswordCell.h"
|
||||
|
||||
@interface MPPasswordStoredCell : MPPasswordCell
|
||||
|
||||
- (MPElementStoredEntity *)elementInContext:(NSManagedObjectContext *)context;
|
||||
|
||||
@end
|
73
MasterPassword/ObjC/iOS/MPPasswordStoredCell.m
Normal file
73
MasterPassword/ObjC/iOS/MPPasswordStoredCell.m
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 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 <lhunath@lyndir.com>
|
||||
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
*/
|
||||
|
||||
//
|
||||
// MPPasswordGeneratedCell.h
|
||||
// MPPasswordGeneratedCell
|
||||
//
|
||||
// Created by lhunath on 2014-03-19.
|
||||
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPPasswordStoredCell.h"
|
||||
#import "MPiOSAppDelegate.h"
|
||||
#import "MPAppDelegate_Store.h"
|
||||
|
||||
@interface MPPasswordStoredCell()
|
||||
|
||||
@property(strong, nonatomic) IBOutlet UIButton *editButton;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPPasswordStoredCell
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)doEditContent:(UIButton *)sender {
|
||||
|
||||
self.contentField.enabled = YES;
|
||||
[self.contentField becomeFirstResponder];
|
||||
}
|
||||
|
||||
#pragma mark - UITextFieldDelegate
|
||||
|
||||
- (void)textFieldDidEndEditing:(UITextField *)textField {
|
||||
|
||||
[super textFieldDidEndEditing:textField];
|
||||
|
||||
if (textField == self.contentField) {
|
||||
[MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *mainContext) {
|
||||
if (mainContext) {
|
||||
[[self elementInContext:mainContext] setContentObject:self.contentField.text];
|
||||
[mainContext saveToStore];
|
||||
}
|
||||
|
||||
[self updateAnimated:YES];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (MPElementStoredEntity *)elementInContext:(NSManagedObjectContext *)context {
|
||||
|
||||
return [self storedElement:[super elementInContext:context]];
|
||||
}
|
||||
|
||||
- (MPElementStoredEntity *)storedElement:(MPElementEntity *)element {
|
||||
|
||||
NSAssert([element isKindOfClass:[MPElementStoredEntity class]], @"Element is not of generated type: %@", element.name);
|
||||
if (![element isKindOfClass:[MPElementStoredEntity class]])
|
||||
return nil;
|
||||
|
||||
return (MPElementStoredEntity *)element;
|
||||
}
|
||||
|
||||
@end
|
@ -18,10 +18,11 @@
|
||||
|
||||
#import "LLGitTip.h"
|
||||
|
||||
@interface MPPasswordsViewController : UIViewController<UISearchBarDelegate, UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate, UITextFieldDelegate>
|
||||
@interface MPPasswordsViewController : UIViewController<UISearchBarDelegate, UICollectionViewDataSource, UICollectionViewDelegate, UITextFieldDelegate>
|
||||
|
||||
@property(strong, nonatomic) IBOutlet UIView *passwordSelectionContainer;
|
||||
@property(strong, nonatomic) IBOutlet UICollectionView *passwordCollectionView;
|
||||
@property (strong, nonatomic) IBOutlet UISearchBar *passwordsSearchBar;
|
||||
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *passwordsToBottomConstraint;
|
||||
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *navigationBarToTopConstraint;
|
||||
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *navigationBarToPasswordsConstraint;
|
||||
|
@ -19,10 +19,14 @@
|
||||
#import "MPPasswordsViewController.h"
|
||||
#import "MPiOSAppDelegate.h"
|
||||
#import "MPAppDelegate_Store.h"
|
||||
#import "MPPasswordCell.h"
|
||||
|
||||
@interface MPPasswordsViewController()
|
||||
@property (strong, nonatomic) IBOutlet UINavigationBar *navigationBar;
|
||||
@interface MPPasswordsViewController()<NSFetchedResultsControllerDelegate>
|
||||
|
||||
@property(strong, nonatomic) IBOutlet UINavigationBar *navigationBar;
|
||||
|
||||
@property(nonatomic, readonly) NSString *query;
|
||||
@property(nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
|
||||
@end
|
||||
|
||||
@implementation MPPasswordsViewController {
|
||||
@ -54,28 +58,6 @@
|
||||
[self stopObservingStore];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
|
||||
if (tableView == self.searchDisplayController.searchResultsTableView)
|
||||
return 0;
|
||||
|
||||
NSAssert(NO, @"Unexpected table view: %@", tableView);
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
if (tableView == self.searchDisplayController.searchResultsTableView) {
|
||||
|
||||
}
|
||||
|
||||
NSAssert(NO, @"Unexpected table view: %@", tableView);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UITextFieldDelegate
|
||||
|
||||
- (void)textFieldDidEndEditing:(UITextField *)textField {
|
||||
@ -88,43 +70,99 @@
|
||||
|
||||
// This isn't really in UITextFieldDelegate. We fake it from UITextFieldTextDidChangeNotification.
|
||||
- (void)textFieldDidChange:(UITextField *)textField {
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - UICollectionViewDataSource
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
|
||||
|
||||
return [self.fetchedResultsController.sections count] + 1;
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||
|
||||
if (collectionView == self.passwordCollectionView)
|
||||
return 0;
|
||||
if (collectionView == self.passwordCollectionView) {
|
||||
if (section < [self.fetchedResultsController.sections count])
|
||||
return ((id<NSFetchedResultsSectionInfo>)self.fetchedResultsController.sections[section]).numberOfObjects;
|
||||
|
||||
// New Site.
|
||||
return [self.query length]? 1: 0;
|
||||
}
|
||||
|
||||
Throw(@"unexpected collection view: %@", collectionView);
|
||||
}
|
||||
|
||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
if (collectionView == self.passwordCollectionView)
|
||||
return nil;
|
||||
if (collectionView == self.passwordCollectionView) {
|
||||
MPPasswordCell *cell;
|
||||
if (indexPath.section < [self.fetchedResultsController.sections count]) {
|
||||
MPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath];
|
||||
if (indexPath.item < 2)
|
||||
cell = [collectionView dequeueReusableCellWithReuseIdentifier:[MPPasswordCell reuseIdentifierForElement:element] forIndexPath:indexPath];
|
||||
else
|
||||
cell = [collectionView dequeueReusableCellWithReuseIdentifier:[MPPasswordCell reuseIdentifierForElement:element] forIndexPath:indexPath];
|
||||
|
||||
[cell setElement:element];
|
||||
} else {
|
||||
// New Site.
|
||||
cell = [collectionView dequeueReusableCellWithReuseIdentifier:[MPPasswordCell reuseIdentifier] forIndexPath:indexPath];
|
||||
cell.transientSite = self.query;
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
Throw(@"unexpected collection view: %@", collectionView);
|
||||
}
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
}
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - UILongPressGestureRecognizer
|
||||
|
||||
- (void)didLongPress:(UILongPressGestureRecognizer *)recognizer {
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - UIScrollViewDelegate
|
||||
|
||||
#pragma mark - UISearchBarDelegate
|
||||
|
||||
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
|
||||
|
||||
if (searchBar == self.passwordsSearchBar) {
|
||||
self.passwordsSearchBar.showsCancelButton = YES;
|
||||
|
||||
[UIView animateWithDuration:0.3f animations:^{
|
||||
self.passwordCollectionView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.3f];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
|
||||
|
||||
if (searchBar == self.passwordsSearchBar) {
|
||||
self.passwordsSearchBar.showsCancelButton = NO;
|
||||
|
||||
[UIView animateWithDuration:0.3f animations:^{
|
||||
self.passwordCollectionView.backgroundColor = [UIColor clearColor];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
|
||||
|
||||
[searchBar resignFirstResponder];
|
||||
}
|
||||
|
||||
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
|
||||
|
||||
if (searchBar == self.passwordsSearchBar)
|
||||
[self updatePasswords];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
@ -164,23 +202,24 @@
|
||||
|
||||
- (void)observeStore {
|
||||
|
||||
// Weakify(self);
|
||||
Weakify(self);
|
||||
|
||||
NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady];
|
||||
if (!_mocObserver && mainContext)
|
||||
_mocObserver = [[NSNotificationCenter defaultCenter]
|
||||
addObserverForName:NSManagedObjectContextObjectsDidChangeNotification object:mainContext
|
||||
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady];
|
||||
if (!_mocObserver && mainContext)
|
||||
_mocObserver = [[NSNotificationCenter defaultCenter]
|
||||
addObserverForName:NSManagedObjectContextObjectsDidChangeNotification object:mainContext
|
||||
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
// Strongify(self);
|
||||
// [self updateMode]; TODO: reload passwords list
|
||||
}];
|
||||
if (!_storeObserver)
|
||||
_storeObserver = [[NSNotificationCenter defaultCenter]
|
||||
addObserverForName:USMStoreDidChangeNotification object:nil
|
||||
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
// Strongify(self);
|
||||
// [self updateMode]; TODO: reload passwords list
|
||||
}];
|
||||
}];
|
||||
if (!_storeObserver)
|
||||
_storeObserver = [[NSNotificationCenter defaultCenter]
|
||||
addObserverForName:USMStoreDidChangeNotification object:nil
|
||||
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
Strongify(self);
|
||||
self.fetchedResultsController = nil;
|
||||
[self updatePasswords];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)stopObservingStore {
|
||||
@ -191,8 +230,49 @@
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:_storeObserver];
|
||||
}
|
||||
|
||||
- (void)updatePasswords {
|
||||
|
||||
[self.fetchedResultsController.managedObjectContext performBlock:^{
|
||||
NSManagedObjectID *activeUserOID = [MPiOSAppDelegate get].activeUserOID;
|
||||
if (!activeUserOID)
|
||||
return;
|
||||
|
||||
NSError *error = nil;
|
||||
self.fetchedResultsController.fetchRequest.predicate = [NSPredicate predicateWithFormat:
|
||||
@"user == %@ AND name BEGINSWITH[cd] %@", activeUserOID, self.query];
|
||||
if (![self.fetchedResultsController performFetch:&error])
|
||||
err(@"Couldn't fetch elements: %@", error);
|
||||
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
[self.passwordCollectionView reloadData];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (NSString *)query {
|
||||
|
||||
return [self.passwordsSearchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
}
|
||||
|
||||
- (NSFetchedResultsController *)fetchedResultsController {
|
||||
|
||||
if (!_fetchedResultsController)
|
||||
[MPiOSAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
|
||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )];
|
||||
fetchRequest.sortDescriptors = @[
|
||||
[[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector(lastUsed) ) ascending:NO]
|
||||
];
|
||||
fetchRequest.fetchBatchSize = 10;
|
||||
_fetchedResultsController = [[NSFetchedResultsController alloc]
|
||||
initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
|
||||
_fetchedResultsController.delegate = self;
|
||||
}];
|
||||
|
||||
return _fetchedResultsController;
|
||||
}
|
||||
|
||||
- (void)setActive:(BOOL)active {
|
||||
|
||||
[self setActive:active animated:YES];
|
||||
|
@ -13,6 +13,7 @@
|
||||
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; };
|
||||
93D3932889B6B4206E66A6D6 /* PearlEMail.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */; };
|
||||
93D393543ACC701C018C74DA /* PearlUIView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393676C32D23A47E27957 /* PearlUIView.m */; };
|
||||
93D394F6D3F6E2553AA0D684 /* MPPasswordStoredCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3947F6BB69CA9A9124A5D /* MPPasswordStoredCell.m */; };
|
||||
93D3954FCE045A3CC7E804B7 /* MPUsersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399E571F61E50A9BF8FAF /* MPUsersViewController.m */; };
|
||||
93D3957237D303DE2D38C267 /* MPAvatarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39B381350802A194BF332 /* MPAvatarCell.m */; };
|
||||
93D3959643EACF286D0152BA /* PearlUINavigationBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DDDAC305E8ABB4220C7 /* PearlUINavigationBar.m */; };
|
||||
@ -27,9 +28,11 @@
|
||||
93D39B8F90F58A5D158DDBA3 /* MPPasswordsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3924EE15017F8A12CB436 /* MPPasswordsViewController.m */; };
|
||||
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
|
||||
93D39C8AD8EAB747856B3A8C /* LLModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3923B42DA2DA18F287092 /* LLModel.m */; };
|
||||
93D39CB5E2EC1078E898F46A /* MPPasswordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3937863061C3916AF7AD2 /* MPPasswordCell.m */; };
|
||||
93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393310223DDB35218467A /* MPCombinedViewController.m */; };
|
||||
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; };
|
||||
93D39F8A9254177891F38705 /* MPSetupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39A28369954D147E239BA /* MPSetupViewController.m */; };
|
||||
93D39FA97F4C3F69A75D5A03 /* MPPasswordGeneratedCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3993422E207BF0B21D089 /* MPPasswordGeneratedCell.m */; };
|
||||
DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */; };
|
||||
DA095E75172F4CD8001C948B /* MPLogsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3979190DACEBD1F6AE9F4 /* MPLogsViewController.m */; };
|
||||
DA2CA4DD18D28859007798F8 /* NSArray+Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2CA4D918D28859007798F8 /* NSArray+Pearl.m */; };
|
||||
@ -510,11 +513,14 @@
|
||||
93D3924EE15017F8A12CB436 /* MPPasswordsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordsViewController.m; sourceTree = "<group>"; };
|
||||
93D393310223DDB35218467A /* MPCombinedViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCombinedViewController.m; sourceTree = "<group>"; };
|
||||
93D393676C32D23A47E27957 /* PearlUIView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlUIView.m; sourceTree = "<group>"; };
|
||||
93D3937863061C3916AF7AD2 /* MPPasswordCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordCell.m; sourceTree = "<group>"; };
|
||||
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; };
|
||||
93D393BB973253D4BAAC84AA /* PearlEMail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlEMail.m; sourceTree = "<group>"; };
|
||||
93D394077F8FAB8167647187 /* Twitter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Twitter.framework; path = System/Library/Frameworks/Twitter.framework; sourceTree = SDKROOT; };
|
||||
93D3942A356B639724157982 /* PearlOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlOverlay.h; sourceTree = "<group>"; };
|
||||
93D3947F6BB69CA9A9124A5D /* MPPasswordStoredCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordStoredCell.m; sourceTree = "<group>"; };
|
||||
93D3956915634581E737B38C /* PearlNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlNavigationController.m; sourceTree = "<group>"; };
|
||||
93D395BA6B2CFF5F49A4D25F /* MPPasswordStoredCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordStoredCell.h; sourceTree = "<group>"; };
|
||||
93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = "<group>"; };
|
||||
93D3971FE104BB4052484151 /* MPUsersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUsersViewController.h; sourceTree = "<group>"; };
|
||||
93D39730673227EFF6DEFF19 /* MPSetupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSetupViewController.h; sourceTree = "<group>"; };
|
||||
@ -522,6 +528,7 @@
|
||||
93D3983278751A530262F64E /* LLConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLConfig.h; sourceTree = "<group>"; };
|
||||
93D398567FD02DB2647B8CF3 /* PearlNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlNavigationController.h; sourceTree = "<group>"; };
|
||||
93D398C95847261903D781D3 /* NSError+PearlFullDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+PearlFullDescription.h"; sourceTree = "<group>"; };
|
||||
93D3993422E207BF0B21D089 /* MPPasswordGeneratedCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordGeneratedCell.m; sourceTree = "<group>"; };
|
||||
93D399E571F61E50A9BF8FAF /* MPUsersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUsersViewController.m; sourceTree = "<group>"; };
|
||||
93D39A28369954D147E239BA /* MPSetupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSetupViewController.m; sourceTree = "<group>"; };
|
||||
93D39A3CC4D8330831FC8CB4 /* LLToggleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLToggleViewController.h; sourceTree = "<group>"; };
|
||||
@ -530,9 +537,11 @@
|
||||
93D39BA6C5CB452973918B7D /* LLButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLButtonView.h; sourceTree = "<group>"; };
|
||||
93D39BF6BCBDFFE844E7D34C /* LLButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLButtonView.m; sourceTree = "<group>"; };
|
||||
93D39C8E26B06F01566785B7 /* LLToggleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLToggleViewController.m; sourceTree = "<group>"; };
|
||||
93D39CE1138FDA4D3D1B847A /* MPPasswordGeneratedCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordGeneratedCell.h; sourceTree = "<group>"; };
|
||||
93D39CF8ADF4542CDC4CD385 /* MPCombinedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCombinedViewController.h; sourceTree = "<group>"; };
|
||||
93D39DA27D768B53C8B1330C /* MPAvatarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAvatarCell.h; sourceTree = "<group>"; };
|
||||
93D39DDDAC305E8ABB4220C7 /* PearlUINavigationBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlUINavigationBar.m; sourceTree = "<group>"; };
|
||||
93D39E02F69CACAB61C056F8 /* MPPasswordCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordCell.h; sourceTree = "<group>"; };
|
||||
93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlEMail.h; sourceTree = "<group>"; };
|
||||
93D39F9106F2CCFB94283188 /* NSError+PearlFullDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+PearlFullDescription.m"; sourceTree = "<group>"; };
|
||||
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
||||
@ -1682,6 +1691,10 @@
|
||||
93D3971FE104BB4052484151 /* MPUsersViewController.h */,
|
||||
93D393676C32D23A47E27957 /* PearlUIView.m */,
|
||||
93D39083C93D90C4B94541AD /* PearlUIView.h */,
|
||||
93D39E02F69CACAB61C056F8 /* MPPasswordCell.h */,
|
||||
93D3937863061C3916AF7AD2 /* MPPasswordCell.m */,
|
||||
93D395BA6B2CFF5F49A4D25F /* MPPasswordStoredCell.h */,
|
||||
93D3947F6BB69CA9A9124A5D /* MPPasswordStoredCell.m */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@ -2539,6 +2552,8 @@
|
||||
93D39DA27D768B53C8B1330C /* MPAvatarCell.h */,
|
||||
93D39DDDAC305E8ABB4220C7 /* PearlUINavigationBar.m */,
|
||||
93D390EEC85E94D9C888643F /* PearlUINavigationBar.h */,
|
||||
93D3993422E207BF0B21D089 /* MPPasswordGeneratedCell.m */,
|
||||
93D39CE1138FDA4D3D1B847A /* MPPasswordGeneratedCell.h */,
|
||||
);
|
||||
path = iOS;
|
||||
sourceTree = "<group>";
|
||||
@ -3843,6 +3858,9 @@
|
||||
93D3954FCE045A3CC7E804B7 /* MPUsersViewController.m in Sources */,
|
||||
93D3959643EACF286D0152BA /* PearlUINavigationBar.m in Sources */,
|
||||
93D393543ACC701C018C74DA /* PearlUIView.m in Sources */,
|
||||
93D39CB5E2EC1078E898F46A /* MPPasswordCell.m in Sources */,
|
||||
93D39FA97F4C3F69A75D5A03 /* MPPasswordGeneratedCell.m in Sources */,
|
||||
93D394F6D3F6E2553AA0D684 /* MPPasswordStoredCell.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -19,7 +19,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rWM-08-aab" userLabel="User Selection">
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rWM-08-aab" userLabel="Users Root">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
@ -391,15 +391,10 @@
|
||||
<rect key="frame" x="0.0" y="64" width="320" height="504"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<searchBar contentMode="redraw" translatesAutoresizingMaskIntoConstraints="NO" id="oAG-Ea-TOI">
|
||||
<searchBar contentMode="redraw" barStyle="black" searchBarStyle="minimal" placeholder="eg. apple.com" showsBookmarkButton="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oAG-Ea-TOI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="barTintColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<scopeButtonTitles>
|
||||
<string>Title</string>
|
||||
<string>Title</string>
|
||||
</scopeButtonTitles>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="URL"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="nkY-z6-8jd" id="Mfn-aT-vK7"/>
|
||||
</connections>
|
||||
@ -409,28 +404,31 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="Mv1-29-TWx">
|
||||
<size key="itemSize" width="320" height="100"/>
|
||||
<size key="itemSize" width="304" height="100"/>
|
||||
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
||||
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
||||
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
</collectionViewFlowLayout>
|
||||
<cells>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="302-fI-maQ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="100"/>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPPasswordGeneratedCell" id="302-fI-maQ" customClass="MPPasswordGeneratedCell">
|
||||
<rect key="frame" x="8" y="0.0" width="304" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="100"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="304" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="SadwGafy7^Sidu" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="q75-Uz-86O">
|
||||
<rect key="frame" x="8" y="20" width="304" height="37"/>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="SadwGafy7^Sidu" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="q75-Uz-86O">
|
||||
<rect key="frame" x="8" y="20" width="288" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="302-fI-maQ" id="vji-9t-frp"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="apple.com" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="qek-2l-YQf" userLabel="Site Name">
|
||||
<rect key="frame" x="20" y="71" width="280" height="14"/>
|
||||
<rect key="frame" x="20" y="71" width="264" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="">
|
||||
<accessibilityTraits key="traits" none="YES" staticText="YES" summaryElement="YES"/>
|
||||
@ -442,7 +440,7 @@
|
||||
<size key="shadowOffset" width="0.0" height="1"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="1" textAlignment="right" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="I2J-B6-5rE" userLabel="Counter">
|
||||
<rect key="frame" x="236" y="69" width="11" height="19"/>
|
||||
<rect key="frame" x="220" y="69" width="11" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" hint="Site's counter."/>
|
||||
<fontDescription key="fontDescription" name="Copperplate-Bold" family="Copperplate" pointSize="17"/>
|
||||
@ -452,7 +450,7 @@
|
||||
<size key="shadowOffset" width="0.0" height="1"/>
|
||||
</label>
|
||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iLD-rv-uZZ" userLabel="Upgrade">
|
||||
<rect key="frame" x="241" y="56" width="44" height="44"/>
|
||||
<rect key="frame" x="225" y="56" width="44" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
||||
<constraints>
|
||||
@ -468,9 +466,12 @@
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="doUpgrade:" destination="302-fI-maQ" eventType="touchUpInside" id="iaP-5Y-5re"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fQc-Fn-JDq" userLabel="Incrementer">
|
||||
<rect key="frame" x="241" y="56" width="44" height="44"/>
|
||||
<rect key="frame" x="225" y="56" width="44" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" hint="Increments the site counter."/>
|
||||
<gestureRecognizers/>
|
||||
@ -487,9 +488,12 @@
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="doIncrementCounter:" destination="302-fI-maQ" eventType="touchUpInside" id="Aa1-tk-whD"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cOv-2G-EAP" userLabel="User">
|
||||
<rect key="frame" x="276" y="56" width="44" height="44"/>
|
||||
<rect key="frame" x="260" y="56" width="44" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
||||
<constraints>
|
||||
@ -505,6 +509,9 @@
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="doUser:" destination="302-fI-maQ" eventType="touchUpInside" id="Fp9-L4-hlU"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
@ -526,23 +533,34 @@
|
||||
<constraint firstItem="fQc-Fn-JDq" firstAttribute="centerY" secondItem="I2J-B6-5rE" secondAttribute="centerY" id="uR7-lg-A9q"/>
|
||||
<constraint firstItem="qek-2l-YQf" firstAttribute="leading" secondItem="302-fI-maQ" secondAttribute="leading" constant="20" id="wUJ-7N-Z1z"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="contentField" destination="q75-Uz-86O" id="so3-qq-0Lv"/>
|
||||
<outlet property="counterButton" destination="fQc-Fn-JDq" id="1QL-JK-tHn"/>
|
||||
<outlet property="counterLabel" destination="I2J-B6-5rE" id="C4b-gE-XHW"/>
|
||||
<outlet property="loginButton" destination="cOv-2G-EAP" id="WoR-eP-Ztq"/>
|
||||
<outlet property="nameLabel" destination="qek-2l-YQf" id="CcC-PM-kMx"/>
|
||||
<outlet property="upgradeButton" destination="iLD-rv-uZZ" id="OKi-9X-R6F"/>
|
||||
</connections>
|
||||
</collectionViewCell>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="GAB-fT-EFv">
|
||||
<rect key="frame" x="0.0" y="110" width="320" height="100"/>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPPasswordStoredCell" id="GAB-fT-EFv" customClass="MPPasswordStoredCell">
|
||||
<rect key="frame" x="8" y="110" width="304" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="100"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="304" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="45O-9d-keG">
|
||||
<rect key="frame" x="8" y="20" width="304" height="37"/>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="45O-9d-keG">
|
||||
<rect key="frame" x="8" y="20" width="288" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="GAB-fT-EFv" id="tBW-n5-SOj"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="apple.com" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="VNc-fL-Vfa" userLabel="Site Name">
|
||||
<rect key="frame" x="20" y="71" width="280" height="14"/>
|
||||
<rect key="frame" x="20" y="71" width="264" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="">
|
||||
<accessibilityTraits key="traits" none="YES" staticText="YES" summaryElement="YES"/>
|
||||
@ -554,7 +572,7 @@
|
||||
<size key="shadowOffset" width="0.0" height="1"/>
|
||||
</label>
|
||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="UAg-Fn-Iph" userLabel="Edit">
|
||||
<rect key="frame" x="241" y="56" width="44" height="44"/>
|
||||
<rect key="frame" x="225" y="56" width="44" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" hint="Edits the password."/>
|
||||
<constraints>
|
||||
@ -570,9 +588,12 @@
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="doEditContent:" destination="GAB-fT-EFv" eventType="touchUpInside" id="XnF-cN-Z2j"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="T1f-JH-Ppw" userLabel="User">
|
||||
<rect key="frame" x="276" y="56" width="44" height="44"/>
|
||||
<rect key="frame" x="260" y="56" width="44" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
||||
<constraints>
|
||||
@ -588,6 +609,9 @@
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="doUser:" destination="GAB-fT-EFv" eventType="touchUpInside" id="xCm-vG-Hvp"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
@ -605,6 +629,12 @@
|
||||
<constraint firstAttribute="trailing" secondItem="VNc-fL-Vfa" secondAttribute="trailing" constant="20" id="k3u-1Q-cKf"/>
|
||||
<constraint firstItem="45O-9d-keG" firstAttribute="top" secondItem="GAB-fT-EFv" secondAttribute="top" constant="20" id="qIK-xa-HCc"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="contentField" destination="45O-9d-keG" id="b56-gA-eQD"/>
|
||||
<outlet property="editButton" destination="UAg-Fn-Iph" id="VLe-Hk-a9T"/>
|
||||
<outlet property="loginButton" destination="T1f-JH-Ppw" id="KJN-iM-QFu"/>
|
||||
<outlet property="nameLabel" destination="VNc-fL-Vfa" id="kMh-xS-U1W"/>
|
||||
</connections>
|
||||
</collectionViewCell>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="0BZ-lH-jYe">
|
||||
<rect key="frame" x="0.0" y="220" width="155" height="100"/>
|
||||
@ -613,12 +643,15 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="155" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="SadwGafy7^Sidu" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="GQM-CJ-dQd">
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="SadwGafy7^Sidu" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="GQM-CJ-dQd">
|
||||
<rect key="frame" x="8" y="20" width="139" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="0BZ-lH-jYe" id="oQO-GK-fja"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="apple.com" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="QSz-Qk-OvW" userLabel="Site Name">
|
||||
<rect key="frame" x="20" y="71" width="115" height="14"/>
|
||||
@ -686,19 +719,22 @@
|
||||
</constraints>
|
||||
<size key="customSize" width="155" height="100"/>
|
||||
</collectionViewCell>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="vMF-fk-FYX">
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPPasswordCell" id="vMF-fk-FYX" customClass="MPPasswordCell">
|
||||
<rect key="frame" x="165" y="220" width="155" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="155" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="fmG-ML-oLT">
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="fmG-ML-oLT">
|
||||
<rect key="frame" x="8" y="20" width="139" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="vMF-fk-FYX" id="m0K-yd-GFJ"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="apple.com" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="IgW-NX-sao" userLabel="Site Name">
|
||||
<rect key="frame" x="20" y="71" width="115" height="14"/>
|
||||
@ -729,6 +765,9 @@
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="doUser:" destination="vMF-fk-FYX" eventType="touchUpInside" id="bFe-ar-oI7"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
@ -745,6 +784,11 @@
|
||||
<constraint firstAttribute="trailing" secondItem="GLO-mQ-h0v" secondAttribute="trailing" id="yXU-bt-rwt"/>
|
||||
</constraints>
|
||||
<size key="customSize" width="155" height="100"/>
|
||||
<connections>
|
||||
<outlet property="contentField" destination="fmG-ML-oLT" id="G9g-Nm-5O4"/>
|
||||
<outlet property="loginButton" destination="GLO-mQ-h0v" id="s2n-qw-Pu6"/>
|
||||
<outlet property="nameLabel" destination="IgW-NX-sao" id="zUR-nh-FUZ"/>
|
||||
</connections>
|
||||
</collectionViewCell>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="yRD-Rk-pNt">
|
||||
<rect key="frame" x="0.0" y="330" width="155" height="100"/>
|
||||
@ -753,12 +797,15 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="155" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="2iC-wr-tcf">
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="2iC-wr-tcf">
|
||||
<rect key="frame" x="8" y="20" width="139" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="yRD-Rk-pNt" id="Gcn-G5-0Je"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="apple.com" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="9DA-ac-KNn" userLabel="Site Name">
|
||||
<rect key="frame" x="20" y="71" width="115" height="14"/>
|
||||
@ -813,12 +860,15 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="155" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="vmd-6A-sMl">
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="vmd-6A-sMl">
|
||||
<rect key="frame" x="8" y="20" width="139" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="0w1-b0-Hlj" id="3ia-Ph-fjc"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="apple.com" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="fmF-pH-pLd" userLabel="Site Name">
|
||||
<rect key="frame" x="20" y="71" width="115" height="14"/>
|
||||
@ -873,12 +923,15 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="155" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="Ksb-AB-je4">
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="Ksb-AB-je4">
|
||||
<rect key="frame" x="8" y="20" width="139" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="3uT-QC-zue" id="XFD-25-rYU"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="apple.com" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="stt-hA-Evt" userLabel="Site Name">
|
||||
<rect key="frame" x="20" y="71" width="115" height="14"/>
|
||||
@ -933,12 +986,15 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="155" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="8X9-yV-BkP">
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Pa$sW0rD" textAlignment="center" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="8X9-yV-BkP">
|
||||
<rect key="frame" x="8" y="20" width="139" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Hfe-CZ-2BC" id="hP6-WH-1Gy"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="apple.com" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="RRk-AC-RlV" userLabel="Site Name">
|
||||
<rect key="frame" x="20" y="71" width="115" height="14"/>
|
||||
@ -987,6 +1043,16 @@
|
||||
<size key="customSize" width="155" height="100"/>
|
||||
</collectionViewCell>
|
||||
</cells>
|
||||
<collectionReusableView key="sectionHeaderView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="ef2-bN-Zyo">
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</collectionReusableView>
|
||||
<collectionReusableView key="sectionFooterView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="JAE-Ae-oH9">
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</collectionReusableView>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="nkY-z6-8jd" id="5DW-tc-rAp"/>
|
||||
<outlet property="delegate" destination="nkY-z6-8jd" id="xhr-Qn-SBe"/>
|
||||
</connections>
|
||||
</collectionView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="viewFlipsideBackgroundColor"/>
|
||||
@ -1036,20 +1102,11 @@
|
||||
<outlet property="navigationBarToTopConstraint" destination="AkN-iE-w6G" id="kw0-4E-iQG"/>
|
||||
<outlet property="passwordCollectionView" destination="aXw-tn-8Sj" id="fNR-qS-qNP"/>
|
||||
<outlet property="passwordSelectionContainer" destination="tI8-OT-LrO" id="J91-sd-kq3"/>
|
||||
<outlet property="passwordsSearchBar" destination="oAG-Ea-TOI" id="sqL-H5-LCV"/>
|
||||
<outlet property="passwordsToBottomConstraint" destination="dNt-uf-8BC" id="Ta6-eL-z7w"/>
|
||||
<outlet property="searchDisplayController" destination="y1f-AK-Hd5" id="chz-MM-BSf"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="APh-u5-vFI" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<searchDisplayController id="y1f-AK-Hd5">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="nkY-z6-8jd" id="Cqs-L6-YSJ"/>
|
||||
<outlet property="searchBar" destination="oAG-Ea-TOI" id="FFP-s6-tPm"/>
|
||||
<outlet property="searchContentsController" destination="nkY-z6-8jd" id="SXm-1E-vs9"/>
|
||||
<outlet property="searchResultsDataSource" destination="nkY-z6-8jd" id="el3-A9-EfV"/>
|
||||
<outlet property="searchResultsDelegate" destination="nkY-z6-8jd" id="cuI-bo-AX8"/>
|
||||
</connections>
|
||||
</searchDisplayController>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1350" y="1200"/>
|
||||
</scene>
|
||||
|
Loading…
Reference in New Issue
Block a user