2
0

Initial page-flip other apps, emergency password copy and marquee hint.

[ADDED]     Initial page-flip animation on opening of other apps VC to make it clear to the user that pages can be flipped.
[ADDED]     Copying of password from emergency generator.
[ADDED]     Marquee animate the bottom tip to also hint about the emergency generator.
This commit is contained in:
Maarten Billemont 2013-04-20 11:44:26 -04:00
parent ac1358a0ec
commit eeac1d0dd3
4 changed files with 327 additions and 71 deletions

View File

@ -60,9 +60,6 @@
[self.pagePositionView removeFromSuperview];
[self.pageViewController didMoveToParentViewController:self];
[self.pageViewController setViewControllers:@[[self.pageVCs objectAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward
animated:NO completion:nil];
[super viewDidLoad];
}
@ -75,6 +72,9 @@
#endif
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointApps attributes:nil];
[self.pageViewController setViewControllers:@[ [self.pageVCs objectAtIndex:1] ] direction:UIPageViewControllerNavigationDirectionForward
animated:NO completion:nil];
[super viewWillAppear:animated];
}
@ -82,6 +82,9 @@
[[LocalyticsSession sharedLocalyticsSession] tagScreen:@"Apps"];
[self.pageViewController setViewControllers:@[ [self.pageVCs objectAtIndex:0] ] direction:UIPageViewControllerNavigationDirectionForward
animated:YES completion:nil];
[super viewDidAppear:animated];
}

View File

@ -31,9 +31,11 @@
@property (weak, nonatomic) IBOutlet UITextField *emergencyMasterPassword;
@property (weak, nonatomic) IBOutlet UITextField *emergencySite;
@property (weak, nonatomic) IBOutlet UIStepper *emergencyCounterStepper;
@property (weak, nonatomic) IBOutlet UISegmentedControl *emergencyType;
@property (weak, nonatomic) IBOutlet UISegmentedControl *emergencyTypeControl;
@property (weak, nonatomic) IBOutlet UILabel *emergencyCounter;
@property (weak, nonatomic) IBOutlet UITextField *emergencyPassword;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *emergencyActivity;
@property (weak, nonatomic) IBOutlet UIButton *emergencyPassword;
@property (weak, nonatomic) IBOutlet UIView *contentTipContainer;
@property (nonatomic, strong) UIColor *avatarShadowColor;
@ -43,6 +45,7 @@
- (IBAction)google:(UIButton *)sender;
- (IBAction)mail:(UIButton *)sender;
- (IBAction)add:(UIButton *)sender;
- (IBAction)closeEmergency;
- (IBAction)emergencyClose:(UIButton *)sender;
- (IBAction)emergencyCopy:(UIButton *)sender;
@end

View File

@ -23,6 +23,9 @@
@property(nonatomic, strong) NSOperationQueue *emergencyQueue;
@property(nonatomic, strong) MPKey *emergencyKey;
@property(nonatomic, strong) NSTimer *marqueeTipTimer;
@property(nonatomic) NSUInteger marqueeTipTextIndex;
@property(nonatomic, strong) NSArray *marqueeTipTexts;
@end
@implementation MPUnlockViewController {
@ -126,18 +129,20 @@
self.spinner.alpha = 0;
self.passwordTipView.hidden = NO;
self.createPasswordTipView.hidden = NO;
self.emergencyPassword.text = @"";
[self.emergencyPassword setTitle:@"" forState:UIControlStateNormal];
self.emergencyGeneratorContainer.alpha = 0;
self.emergencyGeneratorContainer.hidden = YES;
self.emergencyQueue = [NSOperationQueue new];
[self.emergencyCounterStepper addTargetBlock:^(id sender, UIControlEvents event) {
self.emergencyCounter.text = PearlString( @"%d", (NSUInteger)self.emergencyCounterStepper.value);
[self updateEmergencyPassword];
} forControlEvents:UIControlEventValueChanged];
[self.emergencyType addTargetBlock:^(id sender, UIControlEvents event) {
[self.emergencyTypeControl addTargetBlock:^(id sender, UIControlEvents event) {
[self updateEmergencyPassword];
} forControlEvents:UIControlEventValueChanged];
} forControlEvents:UIControlEventValueChanged];
self.marqueeTipTexts = @[ @"Tap and hold to delete or reset user.",
@"Shake for emergency generator." ];
NSMutableArray *wordListLines = [NSMutableArray arrayWithCapacity:27413];
[[[NSString alloc] initWithData:[NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"dictionary" withExtension:@"lst"]]
@ -163,7 +168,7 @@
}];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:nil
usingBlock:^(NSNotification *note) {
[self closeEmergencyAnimated:NO];
[self emergencyCloseAnimated:NO];
self.uiContainer.alpha = 0;
}];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil
@ -197,7 +202,6 @@
- (void)viewDidAppear:(BOOL)animated {
dbg(@"Lock screen did appear: %@", animated? @"animated": @"not animated");
if (!animated)
[[self findTargetedAvatar] setSelected:YES];
else
@ -207,6 +211,9 @@
self.uiContainer.alpha = 1;
}];
[self.marqueeTipTimer invalidate];
self.marqueeTipTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(marqueeTip) userInfo:nil repeats:YES];
[[LocalyticsSession sharedLocalyticsSession] tagScreen:@"Unlock"];
[super viewDidAppear:animated];
@ -215,7 +222,9 @@
- (void)viewWillDisappear:(BOOL)animated {
inf(@"Lock screen will disappear");
[self closeEmergencyAnimated:animated];
[self emergencyCloseAnimated:animated];
[self.marqueeTipTimer invalidate];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
@ -237,7 +246,7 @@
self.emergencyGeneratorContainer.alpha = 0;
self.emergencyGeneratorContainer.hidden = NO;
[UIView animateWithDuration:1 animations:^{
[UIView animateWithDuration:0.5 animations:^{
self.emergencyGeneratorContainer.alpha = 1;
} completion:^(BOOL finished) {
[self.emergencyName becomeFirstResponder];
@ -245,14 +254,26 @@
}
}
- (void)marqueeTip {
[UIView animateWithDuration:0.5 animations:^{
self.tip.alpha = 0;
} completion:^(BOOL finished) {
if (!finished)
return;
self.tip.text = self.marqueeTipTexts[++self.marqueeTipTextIndex % [self.marqueeTipTexts count]];
[UIView animateWithDuration:0.5 animations:^{
self.tip.alpha = 1;
}];
}];
}
- (void)updateUsers {
NSManagedObjectContext *moc = [MPAppDelegate managedObjectContextForThreadIfReady];
if (!moc)
return;
self.tip.text = @"Tap and hold to delete or reset user.";
__block NSArray *users = nil;
[moc performBlockAndWait:^{
NSError *error = nil;
@ -794,7 +815,8 @@
return;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.emergencyPassword.text = @"...";
[self.emergencyActivity startAnimating];
[self.emergencyPassword setTitle:@"" forState:UIControlStateNormal];
NSString *masterPassword = self.emergencyMasterPassword.text;
NSString *userName = self.emergencyName.text;
@ -807,71 +829,101 @@
}];
}
- (MPElementType)emergencyType {
switch (self.emergencyTypeControl.selectedSegmentIndex) {
case 0:
return MPElementTypeGeneratedMaximum;
case 1:
return MPElementTypeGeneratedLong;
case 2:
return MPElementTypeGeneratedMedium;
case 3:
return MPElementTypeGeneratedBasic;
case 4:
return MPElementTypeGeneratedShort;
case 5:
return MPElementTypeGeneratedPIN;
default:
Throw(@"Unsupported type index: %d", self.emergencyTypeControl.selectedSegmentIndex);
}
}
- (void)updateEmergencyPassword {
if (!self.emergencyKey || ![self.emergencySite.text length])
return;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.emergencyPassword.text = @"...";
[self.emergencyPassword setTitle:@"" forState:UIControlStateNormal];
NSString *name = self.emergencySite.text;
NSUInteger counter = (NSUInteger)self.emergencyCounterStepper.value;
MPElementType type;
switch (self.emergencyType.selectedSegmentIndex) {
case 0:
type = MPElementTypeGeneratedMaximum;
break;
case 1:
type = MPElementTypeGeneratedLong;
break;
case 2:
type = MPElementTypeGeneratedMedium;
break;
case 3:
type = MPElementTypeGeneratedBasic;
break;
case 4:
type = MPElementTypeGeneratedShort;
break;
case 5:
type = MPElementTypeGeneratedPIN;
break;
default:
Throw(@"Unsupported type index: %d", self.emergencyType.selectedSegmentIndex);
}
[self.emergencyQueue addOperationWithBlock:^{
NSString *content = [MPAlgorithmDefault generateContentNamed:name ofType:type withCounter:counter usingKey:self.emergencyKey];
NSString *content = [MPAlgorithmDefault generateContentNamed:name ofType:[self emergencyType]
withCounter:counter usingKey:self.emergencyKey];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.emergencyPassword.text = content;
[self.emergencyActivity stopAnimating];
[self.emergencyPassword setTitle:content forState:UIControlStateNormal];
}];
}];
}];
}
- (IBAction)closeEmergency {
- (IBAction)emergencyClose:(UIButton *)sender {
[self closeEmergencyAnimated:YES];
[self emergencyCloseAnimated:YES];
}
- (void)closeEmergencyAnimated:(BOOL)animated {
- (IBAction)emergencyCopy:(UIButton *)sender {
inf(@"Copying emergency password for: %@", self.emergencyName.text);
[UIPasteboard generalPasteboard].string = [self.emergencyPassword titleForState:UIControlStateNormal];
[UIView animateWithDuration:0.3f animations:^{
self.contentTipContainer.alpha = 1;
} completion:^(BOOL finished) {
if (finished) {
dispatch_time_t popTime = dispatch_time( DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC );
dispatch_after( popTime, dispatch_get_main_queue(), ^(void) {
[UIView animateWithDuration:0.2f animations:^{
self.contentTipContainer.alpha = 0;
}];
} );
}
}];
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPCheckpointCopyToPasteboard];
#endif
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointCopyToPasteboard attributes:@{
@"type" : [MPAlgorithmDefault nameOfType:self.emergencyType],
@"version" : @MPAlgorithmDefaultVersion,
@"emergency" : @YES,
}];
}
- (void)emergencyCloseAnimated:(BOOL)animated {
[[self.emergencyGeneratorContainer findFirstResponderInHierarchy] resignFirstResponder];
if (animated) {
[UIView animateWithDuration:0.5 animations:^{
[self closeEmergencyAnimated:NO];
self.emergencyGeneratorContainer.alpha = 0;
} completion:^(BOOL finished) {
[self emergencyCloseAnimated:NO];
}];
return;
}
self.emergencyName.text = @"";
self.emergencyMasterPassword.text = @"";
self.emergencySite.text = @"";
self.emergencyCounterStepper.value = 0;
self.emergencyPassword.text = @"";
[self.emergencyPassword setTitle:@"" forState:UIControlStateNormal];
[self.emergencyActivity stopAnimating];
self.emergencyGeneratorContainer.alpha = 0;
self.emergencyGeneratorContainer.hidden = YES;
}

View File

@ -1513,6 +1513,19 @@ You could use the word wall for inspiration in finding a memorable master passw
<outlet property="delegate" destination="Nbn-Rv-sP1" id="w1h-rQ-fIF"/>
</connections>
</textField>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="1" id="LfH-XT-9Vt">
<rect key="frame" x="41" y="223" width="240" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="Max"/>
<segment title="Long"/>
<segment title="Med"/>
<segment title="Basic"/>
<segment title="Short"/>
<segment title="PIN"/>
</segments>
<color key="tintColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
</segmentedControl>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Counter" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" id="pa9-d6-vQt">
<rect key="frame" x="41" y="262" width="285" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
@ -1546,19 +1559,31 @@ You could use the word wall for inspiration in finding a memorable master passw
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="closeEmergency" destination="Nbn-Rv-sP1" eventType="touchUpInside" id="TgI-O2-XiW"/>
<action selector="emergencyClose:" destination="Nbn-Rv-sP1" eventType="touchUpInside" id="U2r-pg-UGB"/>
</connections>
</button>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Kucy9-RimuTich" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" id="WAX-03-cSy" userLabel="Text Field - Content">
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" hidesWhenStopped="YES" style="whiteLarge" id="3Ax-91-gVM">
<rect key="frame" x="141.5" y="300" width="37" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
</activityIndicatorView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="r9J-C9-Bt1">
<rect key="frame" x="20" y="292" width="280" height="54"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" hint=""/>
<color key="textColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done"/>
</textField>
<size key="titleShadowOffset" width="0.0" height="1"/>
<state key="normal" title="Kucy9-RimuTich">
<color key="titleColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="emergencyCopy:" destination="Nbn-Rv-sP1" eventType="touchUpInside" id="p7g-5T-dqz"/>
</connections>
</button>
<view hidden="YES" userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" id="sD9-hR-UAI" userLabel="View - Content Tip">
<rect key="frame" x="55" y="320" width="210" height="60"/>
<rect key="frame" x="55" y="266" width="210" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" id="Lua-xm-WX6">
@ -1575,19 +1600,6 @@ You could use the word wall for inspiration in finding a memorable master passw
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="1" id="LfH-XT-9Vt">
<rect key="frame" x="41" y="223" width="240" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="Max"/>
<segment title="Long"/>
<segment title="Med"/>
<segment title="Basic"/>
<segment title="Short"/>
<segment title="PIN"/>
</segments>
<color key="tintColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
</segmentedControl>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
@ -1605,15 +1617,17 @@ You could use the word wall for inspiration in finding a memorable master passw
<connections>
<outlet property="avatarTemplate" destination="Ten-ig-gog" id="0ZZ-z5-d5m"/>
<outlet property="avatarsView" destination="Blg-F1-9NA" id="2NL-jU-IMI"/>
<outlet property="contentTipContainer" destination="sD9-hR-UAI" id="RiP-k1-7dk"/>
<outlet property="createPasswordTipView" destination="xWL-xQ-KjX" id="Pa1-Bk-pW2"/>
<outlet property="emergencyActivity" destination="3Ax-91-gVM" id="UfN-vk-k0Z"/>
<outlet property="emergencyCounter" destination="TJC-xD-fjQ" id="jrf-nb-soB"/>
<outlet property="emergencyCounterStepper" destination="D49-fo-7FA" id="hj2-CL-zxq"/>
<outlet property="emergencyGeneratorContainer" destination="KNa-Xb-RuE" id="6jt-vU-L2Q"/>
<outlet property="emergencyMasterPassword" destination="Yvd-Hm-fuw" id="pnx-sH-P8R"/>
<outlet property="emergencyName" destination="esC-1q-bE7" id="ifH-bh-MhW"/>
<outlet property="emergencyPassword" destination="WAX-03-cSy" id="lLN-BO-OQ8"/>
<outlet property="emergencyPassword" destination="r9J-C9-Bt1" id="yt0-hH-0yT"/>
<outlet property="emergencySite" destination="YeH-3J-oY4" id="h0w-om-4vd"/>
<outlet property="emergencyType" destination="LfH-XT-9Vt" id="pku-x3-i9h"/>
<outlet property="emergencyTypeControl" destination="LfH-XT-9Vt" id="pku-x3-i9h"/>
<outlet property="nameLabel" destination="0NM-NI-7UR" id="GBg-Ry-sqj"/>
<outlet property="newsView" destination="rGU-aZ-XVm" id="p1r-Wf-YIY"/>
<outlet property="oldNameLabel" destination="8s0-nT-Aoq" id="plu-1H-MVc"/>
@ -2796,6 +2810,190 @@ However, it means that anyone who finds your device unlocked can do the same.</s
<image name="ui_textfield.png" width="158" height="34"/>
<image name="unlocked.png" width="84" height="80"/>
</resources>
<classes>
<class className="MPAppViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPAppViewController.h"/>
<relationships>
<relationship kind="action" name="deblock:" candidateClass="UIButton"/>
<relationship kind="action" name="gorillas:" candidateClass="UIButton"/>
</relationships>
</class>
<class className="MPAppsViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPAppsViewController.h"/>
<relationships>
<relationship kind="action" name="exit"/>
<relationship kind="outlet" name="pagePositionView" candidateClass="UIImageView"/>
</relationships>
</class>
<class className="MPElementListAllViewController" superclassName="MPElementListController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPElementListAllViewController.h"/>
<relationships>
<relationship kind="action" name="add:"/>
<relationship kind="action" name="close:"/>
<relationship kind="outlet" name="navigationBar" candidateClass="UINavigationBar"/>
</relationships>
</class>
<class className="MPElementListController" superclassName="UITableViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPElementListController.h"/>
<relationships>
<relationship kind="outlet" name="delegate"/>
</relationships>
</class>
<class className="MPElementListSearchController" superclassName="MPElementListController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPElementListSearchController.h"/>
<relationships>
<relationship kind="outlet" name="searchDisplayController" candidateClass="UISearchDisplayController"/>
<relationship kind="outlet" name="searchTipContainer" candidateClass="UIView"/>
</relationships>
</class>
<class className="MPGuideViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPGuideViewController.h"/>
<relationships>
<relationship kind="action" name="close"/>
<relationship kind="action" name="play"/>
<relationship kind="action" name="toggleVolume"/>
<relationship kind="outlet" name="content" candidateClass="UIView"/>
<relationship kind="outlet" name="contentButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="contentText" candidateClass="UITextField"/>
<relationship kind="outlet" name="contentTip" candidateClass="UIView"/>
<relationship kind="outlet" name="contentTipText" candidateClass="UILabel"/>
<relationship kind="outlet" name="largePlayButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="progress" candidateClass="UIProgressView"/>
<relationship kind="outlet" name="siteNameTip" candidateClass="UIView"/>
<relationship kind="outlet" name="smallPlayButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="toolButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="toolTip" candidateClass="UIView"/>
<relationship kind="outlet" name="typeButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="typeTip" candidateClass="UIView"/>
<relationship kind="outlet" name="usernameButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="usernameTip" candidateClass="UIView"/>
<relationship kind="outlet" name="volumeButton" candidateClass="UIButton"/>
</relationships>
</class>
<class className="MPMainViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPMainViewController.h"/>
<relationships>
<relationship kind="action" name="action:" candidateClass="UIBarButtonItem"/>
<relationship kind="action" name="closeAlert"/>
<relationship kind="action" name="closeOutdatedAlert"/>
<relationship kind="action" name="copyContent"/>
<relationship kind="action" name="editLoginName:" candidateClass="UILongPressGestureRecognizer"/>
<relationship kind="action" name="editPassword"/>
<relationship kind="action" name="incrementPasswordCounter"/>
<relationship kind="action" name="infoOutdatedAlert"/>
<relationship kind="action" name="panHelpDown:" candidateClass="UIPanGestureRecognizer"/>
<relationship kind="action" name="panHelpUp:" candidateClass="UIPanGestureRecognizer"/>
<relationship kind="action" name="resetPasswordCounter:" candidateClass="UILongPressGestureRecognizer"/>
<relationship kind="action" name="searchOutdatedElements"/>
<relationship kind="action" name="toggleUser"/>
<relationship kind="action" name="upgradePassword"/>
<relationship kind="outlet" name="actionsTipContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="alertBody" candidateClass="UITextView"/>
<relationship kind="outlet" name="alertContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="alertTitle" candidateClass="UILabel"/>
<relationship kind="outlet" name="contentContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="contentField" candidateClass="UITextField"/>
<relationship kind="outlet" name="contentTipBody" candidateClass="UILabel"/>
<relationship kind="outlet" name="contentTipContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="displayContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="helpContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="helpView" candidateClass="UIWebView"/>
<relationship kind="outlet" name="loginNameContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="loginNameField" candidateClass="UITextField"/>
<relationship kind="outlet" name="loginNameTipBody" candidateClass="UILabel"/>
<relationship kind="outlet" name="loginNameTipContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="outdatedAlertBack" candidateClass="UIImageView"/>
<relationship kind="outlet" name="outdatedAlertCloseButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="outdatedAlertContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="passwordCounter" candidateClass="UILabel"/>
<relationship kind="outlet" name="passwordEdit" candidateClass="UIButton"/>
<relationship kind="outlet" name="passwordIncrementer" candidateClass="UIButton"/>
<relationship kind="outlet" name="passwordUpgrade" candidateClass="UIButton"/>
<relationship kind="outlet" name="passwordUser" candidateClass="UIButton"/>
<relationship kind="outlet" name="pullDownGesture" candidateClass="UIPanGestureRecognizer"/>
<relationship kind="outlet" name="pullDownView" candidateClass="UIImageView"/>
<relationship kind="outlet" name="pullUpGesture" candidateClass="UIPanGestureRecognizer"/>
<relationship kind="outlet" name="pullUpView" candidateClass="UIImageView"/>
<relationship kind="outlet" name="searchDelegate" candidateClass="MPElementListSearchController"/>
<relationship kind="outlet" name="searchTipContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="siteName" candidateClass="UILabel"/>
<relationship kind="outlet" name="toolTipBody" candidateClass="UILabel"/>
<relationship kind="outlet" name="toolTipContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="toolTipEditIcon" candidateClass="UIImageView"/>
<relationship kind="outlet" name="typeButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="typeTipContainer" candidateClass="UIView"/>
</relationships>
</class>
<class className="MPPreferencesViewController" superclassName="UITableViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPPreferencesViewController.h"/>
<relationships>
<relationship kind="action" name="didToggleSwitch:" candidateClass="UISwitch"/>
<relationship kind="action" name="settings:"/>
<relationship kind="outlet" name="avatarTemplate" candidateClass="UIButton"/>
<relationship kind="outlet" name="avatarsView" candidateClass="UIScrollView"/>
<relationship kind="outlet" name="changeMPCell" candidateClass="UITableViewCell"/>
<relationship kind="outlet" name="defaultTypeLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="exportCell" candidateClass="UITableViewCell"/>
<relationship kind="outlet" name="savePasswordSwitch" candidateClass="UISwitch"/>
</relationships>
</class>
<class className="MPSetupViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPSetupViewController.h"/>
<relationships>
<relationship kind="action" name="close:" candidateClass="UIBarButtonItem"/>
<relationship kind="outlet" name="cloudSwitch" candidateClass="UISwitch"/>
<relationship kind="outlet" name="rememberLoginSwitch" candidateClass="UISwitch"/>
</relationships>
</class>
<class className="MPTypeViewController" superclassName="UITableViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPTypeViewController.h"/>
<relationships>
<relationship kind="outlet" name="recommendedTipContainer" candidateClass="UIView"/>
</relationships>
</class>
<class className="MPUnlockViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPUnlockViewController.h"/>
<relationships>
<relationship kind="action" name="add:" candidateClass="UIButton"/>
<relationship kind="action" name="emergencyClose:" candidateClass="UIButton"/>
<relationship kind="action" name="emergencyCopy:" candidateClass="UIButton"/>
<relationship kind="action" name="facebook:" candidateClass="UIButton"/>
<relationship kind="action" name="google:" candidateClass="UIButton"/>
<relationship kind="action" name="mail:" candidateClass="UIButton"/>
<relationship kind="action" name="targetedUserAction:" candidateClass="UILongPressGestureRecognizer"/>
<relationship kind="action" name="twitter:" candidateClass="UIButton"/>
<relationship kind="outlet" name="avatarTemplate" candidateClass="UIButton"/>
<relationship kind="outlet" name="avatarsView" candidateClass="UIScrollView"/>
<relationship kind="outlet" name="contentTipContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="createPasswordTipView" candidateClass="UIView"/>
<relationship kind="outlet" name="emergencyActivity" candidateClass="UIActivityIndicatorView"/>
<relationship kind="outlet" name="emergencyCounter" candidateClass="UILabel"/>
<relationship kind="outlet" name="emergencyCounterStepper" candidateClass="UIStepper"/>
<relationship kind="outlet" name="emergencyGeneratorContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="emergencyMasterPassword" candidateClass="UITextField"/>
<relationship kind="outlet" name="emergencyName" candidateClass="UITextField"/>
<relationship kind="outlet" name="emergencyPassword" candidateClass="UIButton"/>
<relationship kind="outlet" name="emergencySite" candidateClass="UITextField"/>
<relationship kind="outlet" name="emergencyTypeControl" candidateClass="UISegmentedControl"/>
<relationship kind="outlet" name="nameLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="newsView" candidateClass="UIWebView"/>
<relationship kind="outlet" name="oldNameLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="passwordField" candidateClass="UITextField"/>
<relationship kind="outlet" name="passwordFieldLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="passwordTipLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="passwordTipView" candidateClass="UIView"/>
<relationship kind="outlet" name="passwordView" candidateClass="UIView"/>
<relationship kind="outlet" name="spinner" candidateClass="UIImageView"/>
<relationship kind="outlet" name="targetedUserActionGesture" candidateClass="UILongPressGestureRecognizer"/>
<relationship kind="outlet" name="tip" candidateClass="UILabel"/>
<relationship kind="outlet" name="uiContainer" candidateClass="UIView"/>
<relationship kind="outlet" name="wordWall" candidateClass="UIView"/>
</relationships>
</class>
<class className="PearlNavigationController" superclassName="UINavigationController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/PearlNavigationController.h"/>
</class>
</classes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<nil key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>