From fc881c87fd7efc40102e72af5ca84e38fdf5af33 Mon Sep 17 00:00:00 2001 From: Kristian Pennacchia Date: Sun, 5 Jun 2011 10:58:30 -0700 Subject: [PATCH] Feature: Added notification bar swiping. Modified: Split loadView method into two parts (loadView and loadViewInfo) to avoid code duplication. Modified: a few other pieces of code to accomodate the new feature. --- MNAlertViewController.m | 273 ++++++++++++++++++++++++++++------------ 1 file changed, 193 insertions(+), 80 deletions(-) diff --git a/MNAlertViewController.m b/MNAlertViewController.m index a9ba422..8e2857d 100644 --- a/MNAlertViewController.m +++ b/MNAlertViewController.m @@ -1,3 +1,4 @@ + /* Copyright (c) 2010-2011, Peter Hajas All rights reserved. @@ -59,11 +60,14 @@ -(id)init return self; } --(id)initWithMNData:(MNAlertData*) data +-(id)initWithMNData:(MNAlertData*) data pendingAlerts:(NSMutableArray *)_pendingAlerts { self = [super init]; dataObj = data; + + // Might need to use a method for this and not an = operator? + pendingAlerts = _pendingAlerts; return self; } @@ -71,7 +75,10 @@ -(id)initWithMNData:(MNAlertData*) data -(void)loadView { [super loadView]; - + + // Set position of notificationView here + notificationViewRect = CGRectMake(0, 0, 320, 40); + self.view.frame = CGRectMake(0,0,320,40); [UIView setAnimationDidStopSelector:@selector(animationDidStop:didFinish:inContext:)]; @@ -90,24 +97,97 @@ -(void)loadView // Gray alert style alertBackgroundImageView.image = [UIImage imageWithContentsOfFile:@"/Library/Application Support/MobileNotifier/statusbar_alert_bg.png"]; } + + alertExpandButton = [UIButton buttonWithType:UIButtonTypeCustom]; + alertExpandButton.frame = CGRectMake(0.0, 0.0, 320.0, 40.0); + [alertExpandButton setAlpha:0.0]; + + // Popdown alert actions + alertActionBackgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(3.5, 30.0, 313.0, 229.0)]; + alertActionBackgroundImageView.image = [UIImage imageWithContentsOfFile:@"/Library/Application Support/MobileNotifier/popout_bg.png"]; + alertActionBackgroundImageView.opaque = NO; + alertActionBackgroundImageView.backgroundColor = [UIColor clearColor]; + alertActionBackgroundImageView.alpha = 0.0; + + openButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; + openButton.frame = CGRectMake(72.0, 205.0, 46.0, 40.0); + [openButton setBackgroundImage:[UIImage imageWithContentsOfFile: @"/Library/Application Support/MobileNotifier/btn_open.png"] + forState:UIControlStateNormal]; + [openButton setAlpha:0.0]; + + laterButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; + laterButton.frame = CGRectMake(16.0, 205.0, 46.0, 40.0); + [laterButton setBackgroundImage:[UIImage imageWithContentsOfFile: @"/Library/Application Support/MobileNotifier/btn_archive.png"] + forState:UIControlStateNormal]; + [laterButton setAlpha:0.0]; + + closeButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; + closeButton.frame = CGRectMake(274, 7.0, 25.0, 26.0); + + if (useBlackAlertStyle) + { + // Black alert style + [closeButton setBackgroundImage:[UIImage imageWithContentsOfFile: @"/Library/Application Support/MobileNotifier/statusbar_alert_dismiss_black.png"] + forState:UIControlStateNormal]; } + else + { + // Gray alert style + [closeButton setBackgroundImage:[UIImage imageWithContentsOfFile: @"/Library/Application Support/MobileNotifier/statusbar_alert_dismiss.png"] + forState:UIControlStateNormal]; } + + // Wire up buttons + [openButton addTarget:self action:@selector(openPushed:) + forControlEvents:UIControlEventTouchUpInside]; + + [laterButton addTarget:self action:@selector(laterPushed:) + forControlEvents:UIControlEventTouchUpInside]; + + [closeButton addTarget:self action:@selector(closePushed:) + forControlEvents:UIControlEventTouchUpInside]; + + [alertExpandButton addTarget:self action:@selector(chevronPushed:) + forControlEvents:UIControlEventTouchUpInside]; + // Add everything to our view + [self.view addSubview:alertBackgroundImageView]; + + // Release the stuff we don't want to hang on to + [alertBackgroundImageView release]; + + alertIsShowingPopOver = NO; + + [self loadViewInfo]; +} + +-(void)loadViewInfo +{ + // Create and configure the scroll view + notificationScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)]; + [notificationScrollView setDelegate:self]; + [notificationScrollView setAlwaysBounceHorizontal:YES]; + [notificationScrollView setShowsHorizontalScrollIndicator:NO]; + [self.view addSubview:notificationScrollView]; + + // All notification data will go in this view. This way we can keep the + // background image seperate from the notification data. Makes swiping a lot better. + notificationView = [[UIView alloc] initWithFrame:notificationViewRect]; + [notificationScrollView addSubview:notificationView]; + + /* Draw the seperators */ + iconImageView = [[UIImageView alloc] initWithFrame:CGRectMake(17.0, 9.0, 22.5, 22.5)]; iconImageView.image = [_delegate iconForBundleID:dataObj.bundleID]; [iconImageView setAlpha:0.0]; iconImageView.layer.cornerRadius = 5.5; iconImageView.layer.masksToBounds = YES; - - alertExpandButton = [UIButton buttonWithType:UIButtonTypeCustom]; - alertExpandButton.frame = CGRectMake(0.0, 0.0, 320.0, 40.0); - [alertExpandButton setAlpha:0.0]; - + alertHeaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(49.0, 3.0, 216.0, 22.0)]; alertHeaderLabel.adjustsFontSizeToFitWidth = NO; alertHeaderLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:14.000]; alertHeaderLabel.text = dataObj.header; alertHeaderLabel.textAlignment = UITextAlignmentLeft; alertHeaderLabel.backgroundColor = [UIColor clearColor]; - + if (useBlackAlertStyle) { // Black alert style @@ -120,17 +200,17 @@ -(void)loadView alertHeaderLabel.textColor = [UIColor colorWithRed:0.000 green:0.000 blue:0.000 alpha:0.9]; alertHeaderLabel.shadowColor = [UIColor whiteColor]; } - + alertHeaderLabel.shadowOffset = CGSizeMake(0,1); [alertHeaderLabel setAlpha:0.0]; - + alertTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(49.0, 17.0, 216.0, 22.0)]; alertTextLabel.adjustsFontSizeToFitWidth = NO; alertTextLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:11.000]; alertTextLabel.text = dataObj.text; alertTextLabel.textAlignment = UITextAlignmentLeft; alertTextLabel.backgroundColor = [UIColor clearColor]; - + if (useBlackAlertStyle) { // Black alert style @@ -143,10 +223,10 @@ -(void)loadView alertTextLabel.textColor = [UIColor colorWithRed:0.000 green:0.000 blue:0.000 alpha:0.9]; alertTextLabel.shadowColor = [UIColor whiteColor]; } - + alertTextLabel.shadowOffset = CGSizeMake(0,1); [alertTextLabel setAlpha:0.0]; - + detailText = [[UITextView alloc] initWithFrame:CGRectMake(8.0, 50.0, 303.0, 75.0)]; detailText.delegate = self; detailText.font = [UIFont fontWithName:@"HelveticaNeue" size:16.000]; @@ -156,7 +236,7 @@ -(void)loadView detailText.backgroundColor = [UIColor clearColor]; detailText.editable = NO; [detailText setAlpha:0.0]; - + dateText = [[UILabel alloc] initWithFrame:CGRectMake(16.0, 127.0, 65.0, 15.0)]; dateText.font = [UIFont fontWithName:@"HelveticaNeue" size:10.500]; dateText.text = [dataObj.time descriptionWithCalendarFormat:@"%H:%M" timeZone: nil locale: nil]; @@ -164,53 +244,7 @@ -(void)loadView dateText.textColor = [UIColor colorWithRed:1.000 green:1.000 blue:1.000 alpha:0.5]; dateText.backgroundColor = [UIColor clearColor]; [dateText setAlpha:0.0]; - - // Popdown alert actions - alertActionBackgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(3.5, 30.0, 313.0, 229.0)]; - alertActionBackgroundImageView.image = [UIImage imageWithContentsOfFile:@"/Library/Application Support/MobileNotifier/popout_bg.png"]; - alertActionBackgroundImageView.opaque = NO; - alertActionBackgroundImageView.backgroundColor = [UIColor clearColor]; - alertActionBackgroundImageView.alpha = 0.0; - - openButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; - openButton.frame = CGRectMake(72.0, 205.0, 46.0, 40.0); - [openButton setBackgroundImage:[UIImage imageWithContentsOfFile: @"/Library/Application Support/MobileNotifier/btn_open.png"] - forState:UIControlStateNormal]; - [openButton setAlpha:0.0]; - - laterButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; - laterButton.frame = CGRectMake(16.0, 205.0, 46.0, 40.0); - [laterButton setBackgroundImage:[UIImage imageWithContentsOfFile: @"/Library/Application Support/MobileNotifier/btn_archive.png"] - forState:UIControlStateNormal]; - [laterButton setAlpha:0.0]; - - closeButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; - closeButton.frame = CGRectMake(274, 7.0, 25.0, 26.0); - - if (useBlackAlertStyle) - { - // Black alert style - [closeButton setBackgroundImage:[UIImage imageWithContentsOfFile: @"/Library/Application Support/MobileNotifier/statusbar_alert_dismiss_black.png"] - forState:UIControlStateNormal]; } - else - { - // Gray alert style - [closeButton setBackgroundImage:[UIImage imageWithContentsOfFile: @"/Library/Application Support/MobileNotifier/statusbar_alert_dismiss.png"] - forState:UIControlStateNormal]; } - - // Wire up buttons - [openButton addTarget:self action:@selector(openPushed:) - forControlEvents:UIControlEventTouchUpInside]; - - [laterButton addTarget:self action:@selector(laterPushed:) - forControlEvents:UIControlEventTouchUpInside]; - - [closeButton addTarget:self action:@selector(closePushed:) - forControlEvents:UIControlEventTouchUpInside]; - - [alertExpandButton addTarget:self action:@selector(chevronPushed:) - forControlEvents:UIControlEventTouchUpInside]; - + // If we're an SMS alert, we have some more setup to do! if(dataObj.type == kSMSAlert) { @@ -227,10 +261,10 @@ -(void)loadView sendButton.titleLabel.backgroundColor = [UIColor clearColor]; sendButton.titleLabel.shadowColor = [UIColor blackColor]; sendButton.titleLabel.shadowOffset = CGSizeMake(0,-1); - + [sendButton addTarget:self action:@selector(sendPushed:) - forControlEvents:UIControlEventTouchUpInside]; - + forControlEvents:UIControlEventTouchUpInside]; + charactersTyped = [[UILabel alloc] initWithFrame:CGRectMake(258.0, 127.0, 45.0, 15.0)]; charactersTyped.font = [UIFont fontWithName:@"HelveticaNeue" size:10.500]; charactersTyped.text = @"0/160"; @@ -238,38 +272,34 @@ -(void)loadView charactersTyped.textColor = [UIColor colorWithRed:1.000 green:1.000 blue:1.000 alpha:0.5]; charactersTyped.backgroundColor = [UIColor clearColor]; [charactersTyped setAlpha:0.0]; - + textBox = [[BCZeroEdgeTextView alloc] initWithFrame:CGRectMake(17.0, 145.0, 285.0, 50.0)]; [textBox setDelegate:self]; - textBox.keyboardAppearance = UIKeyboardAppearanceAlert; + // textBox.keyboardAppearance = UIKeyboardAppearanceAlert; Semi-Transparent keyboard textBox.keyboardType = UIKeyboardTypeDefault; textBox.returnKeyType = UIReturnKeyDefault; textBox.font = [UIFont fontWithName:@"HelveticaNeue" size:12.500]; textBox.textColor = [UIColor colorWithRed:0.000 green:0.000 blue:0.000 alpha:0.8]; [textBox setAlpha:0.0]; } - + // Add everything to our view - [self.view addSubview:alertBackgroundImageView]; - [self.view addSubview:iconImageView]; - [self.view addSubview:alertHeaderLabel]; - [self.view addSubview:alertTextLabel]; - [self.view addSubview:alertExpandButton]; - + [notificationView addSubview:iconImageView]; + [notificationView addSubview:alertHeaderLabel]; + [notificationView addSubview:alertTextLabel]; + [notificationView addSubview:alertExpandButton]; + // Release the stuff we don't want to hang on to - [alertBackgroundImageView release]; [alertHeaderLabel release]; [alertTextLabel release]; - - alertIsShowingPopOver = NO; - + [self fadeInView]; } -(void)viewDidLoad { [super viewDidLoad]; - + // Detect single finger, double tap /*UITapGestureRecognizer* doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(laterPushed:)]; @@ -281,11 +311,58 @@ -(void)viewDidLoad [doubleTap release];*/ } +-(void)slideAwayRight +{ + if (!alertIsShowingPopOver && isAnimationInProgress == NO) { + if (index != 0) { + isAnimationInProgress = YES; + // Animate slide away to right of screen (newer notification) + [UIView beginAnimations:@"slideAwayToRight" context:nil]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(animationDidStop:didFinish:inContext:)]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; + [UIView setAnimationDuration:0.2]; + [notificationView setFrame:CGRectMake(320,0,320,40)]; + [UIView commitAnimations]; + --index; + } + } +} + +-(void)slideAwayLeft +{ + if (!alertIsShowingPopOver && isAnimationInProgress == NO) { + if (index < [pendingAlerts count] - 1) { + isAnimationInProgress = YES; + // Animate slide away to left of screen (older notification) + [UIView beginAnimations:@"slideAwayToLeft" context:nil]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(animationDidStop:didFinish:inContext:)]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; + [UIView setAnimationDuration:0.2]; + [notificationView setFrame:CGRectMake(-320,0,320,40)]; + [UIView commitAnimations]; + ++index; + } + } +} + +-(void)slideIn +{ + [UIView beginAnimations:@"slideIn" context:nil]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; + [UIView setAnimationDuration:0.2]; + [notificationView setFrame:CGRectMake(0,0,320,40)]; + [UIView commitAnimations]; +} + -(void)chevronPushed:(id)sender { [_delegate alertShowingPopOver:!alertIsShowingPopOver]; if (alertIsShowingPopOver) { + [notificationScrollView setScrollEnabled:YES]; + CGRect frame = self.view.frame; frame.size.height -= 229; self.view.frame = frame; @@ -294,6 +371,8 @@ -(void)chevronPushed:(id)sender } else { + [notificationScrollView setScrollEnabled:NO]; + CGRect frame = self.view.frame; frame.size.height += 229; self.view.frame = frame; @@ -385,6 +464,7 @@ -(void)fadeOutWholeView [detailText setAlpha:0.0]; [dateText setAlpha:0.0]; [closeButton setAlpha:0.0]; + [notificationView setAlpha:0.0]; if (dataObj.type == kSMSAlert) { @@ -411,11 +491,28 @@ -(void)fadeInView [alertHeaderLabel setAlpha:1.0]; [alertTextLabel setAlpha:1.0]; [alertExpandButton setAlpha:1.0]; + [notificationView setAlpha:1.0]; [UIView commitAnimations]; } -(void)animationDidStop:(NSString*)animationID didFinish:(NSNumber*)finished inContext:(id)context { + if ([animationID isEqualToString:@"slideAwayToRight"]) { + // Set the position back to the left side of the screen to be animated back in, going right + // loadViewInfo will do the moving for us + notificationViewRect = CGRectMake(-320,0,320,40); + } + else if ([animationID isEqualToString:@"slideAwayToLeft"]) { + // Set the position back to the right side of the screen to be animated back in, going left + // loadViewInfo will do the moving for us + notificationViewRect = CGRectMake(320,0,320,40); + } + if ([animationID isEqualToString:@"slideAwayToRight"] || [animationID isEqualToString:@"slideAwayToLeft"]) { + isAnimationInProgress = NO; + [self loadData]; + [self slideIn]; + } + if ([animationID isEqualToString:@"fadeInView"]) { [alertActionBackgroundImageView removeFromSuperview]; @@ -439,6 +536,13 @@ -(void)animationDidStop:(NSString*)animationID didFinish:(NSNumber*)finished inC } } +-(void)loadData +{ + dataObj = [pendingAlerts objectAtIndex:index]; + + [self loadViewInfo]; +} + -(void)openPushed:(id)sender { [self fadeOutWholeView]; @@ -499,11 +603,20 @@ -(BOOL)textFieldShouldReturn:(UITextField *)textField -(void)scrollViewDidScroll:(UIScrollView *)scrollView { - if (scrollView.contentOffset.x != 0.0) + if (scrollView == notificationScrollView) { + // If scroll was far enough to the left + if ([notificationScrollView contentOffset].x > 60) { + [self slideAwayLeft]; + } + // If scroll was far enough to the right + else if ([notificationScrollView contentOffset].x < -60) { + [self slideAwayRight]; + } + } + else if (scrollView.contentOffset.x != 0.0) { [scrollView setContentOffset: CGPointMake(0.0, scrollView.contentOffset.y)]; } } @end -