Skip to content

Commit

Permalink
added tap handler. fixes #2
Browse files Browse the repository at this point in the history
By default, supplying a tap handler will disable
```allowTapToDismiss``` on this particular banner. If you want to
reinstate this behavior alongside the tap handler, you can call
```[[ALAlertBannerManager sharedManager]
hideAlertBanner:alertBanner];``` in ```tappedBlock()```.
  • Loading branch information
lobianco committed Aug 28, 2013
1 parent 5dd2aa6 commit 056064c
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 23 deletions.
43 changes: 37 additions & 6 deletions ALAlertBanner/ALAlertBannerManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,37 @@
@interface ALAlertBannerManager : NSObject

/**
Length of time in seconds that a banner should show before auto-hiding. Default is 3.5 seconds. A value <= 0 will disable auto-hiding.
Length of time in seconds that a banner should show before auto-hiding.
Default value is 3.5 seconds. A value <= 0 will disable auto-hiding.
*/
@property (nonatomic) NSTimeInterval secondsToShow;

/**
The length of time it takes a banner to transition on-screen. Default is 0.25 seconds.
The length of time it takes a banner to transition on-screen.
Default value is 0.25 seconds.
*/
@property (nonatomic) NSTimeInterval showAnimationDuration;

/**
The length of time it takes a banner to transition off-screen. Default is 0.2 seconds.
The length of time it takes a banner to transition off-screen.
Default value is 0.2 seconds.
*/
@property (nonatomic) NSTimeInterval hideAnimationDuration;

/**
Banner opacity, between 0 and 1. Default value is 0.93f.
Banner opacity, between 0 and 1.
Default value is 0.93f.
*/
@property (nonatomic, assign) CGFloat bannerOpacity;

/**
Tapping on a banner will dismiss it early. Default is YES.
Tapping on a banner will dismiss it early.
Default value is YES. If you supply a tappedHandler in one of the appropriate methods, this will be set to NO for that specific banner.
*/
@property (nonatomic, assign) BOOL allowTapToDismiss;

Expand All @@ -58,10 +68,31 @@
+(ALAlertBannerManager*)sharedManager;

/**
The default (and only) way to display a banner. All parameters except subtitle must not be nil.
The default methods to display a banner.
*/
-(void)showAlertBannerInView:(UIView*)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString*)title;

-(void)showAlertBannerInView:(UIView*)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString*)title subtitle:(NSString*)subtitle;

/**
Optional method to set the secondsToShow duration on a per-banner basis.
*/
-(void)showAlertBannerInView:(UIView*)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString*)title subtitle:(NSString*)subtitle hideAfter:(NSTimeInterval)secondsToShow;

/**
Optional methods to handle a tap on a banner.
By default, supplying a tap handler will disable allowTapToDismiss on this particular banner. If you want to reinstate this behavior alongside the tap handler, you can call `[[ALAlertBannerManager sharedManager] hideAlertBanner:alertBanner];` in tappedBlock().
*/
-(void)showAlertBannerInView:(UIView*)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString*)title subtitle:(NSString*)subtitle tappedHandler:(void(^)(ALAlertBannerView *alertBanner))tappedBlock;

-(void)showAlertBannerInView:(UIView*)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString*)title subtitle:(NSString*)subtitle hideAfter:(NSTimeInterval)secondsToShow tappedHandler:(void(^)(ALAlertBannerView *alertBanner))tappedBlock;

/**
Immediately hide a specific alert banner.
*/
-(void)hideAlertBanner:(ALAlertBannerView *)alertBanner;

/**
Returns an array of all banners within a certain view.
*/
Expand Down
31 changes: 26 additions & 5 deletions ALAlertBanner/ALAlertBannerManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,25 +102,46 @@ -(id)init
return self;
}

-(void)showAlertBannerInView:(UIView *)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString *)title
{
[self showAlertBannerInView:view style:style position:position title:title subtitle:nil hideAfter:self.secondsToShow tappedHandler:nil];
}

-(void)showAlertBannerInView:(UIView *)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString *)title subtitle:(NSString *)subtitle
{
[self showAlertBannerInView:view style:style position:position title:title subtitle:subtitle hideAfter:self.secondsToShow tappedHandler:nil];
}

-(void)showAlertBannerInView:(UIView *)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString *)title subtitle:(NSString *)subtitle hideAfter:(NSTimeInterval)secondsToShow
{
[self showAlertBannerInView:view style:style position:position title:title subtitle:subtitle hideAfter:secondsToShow tappedHandler:nil];
}

-(void)showAlertBannerInView:(UIView *)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString *)title subtitle:(NSString *)subtitle tappedHandler:(void (^)(ALAlertBannerView *))tappedBlock
{
[self showAlertBannerInView:view style:style position:position title:title subtitle:subtitle hideAfter:self.secondsToShow tappedHandler:tappedBlock];
}

-(void)showAlertBannerInView:(UIView *)view style:(ALAlertBannerStyle)style position:(ALAlertBannerPosition)position title:(NSString *)title subtitle:(NSString *)subtitle hideAfter:(NSTimeInterval)secondsToShow tappedHandler:(void (^)(ALAlertBannerView *))tappedBlock
{
ALAlertBannerView *alertBanner = [ALAlertBannerView alertBannerForView:view style:style position:position title:title subtitle:subtitle];
alertBanner.delegate = self;
alertBanner.tag = arc4random_uniform(SHRT_MAX);
alertBanner.showAnimationDuration = self.showAnimationDuration;
alertBanner.hideAnimationDuration = self.hideAnimationDuration;
alertBanner.allowTapToDismiss = self.allowTapToDismiss;
alertBanner.allowTapToDismiss = tappedBlock ? NO : self.allowTapToDismiss;
alertBanner.isScheduledToHide = NO;
alertBanner.bannerOpacity = self.bannerOpacity;
alertBanner.tappedBlock = tappedBlock;

//keep track of all views we've added banners to, to deal with rotation events and hideAllAlertBanners
if (![self.bannerViews containsObject:view])
[self.bannerViews addObject:view];

[self showAlertBanner:alertBanner];
[self showAlertBanner:alertBanner hideAfter:secondsToShow];
}

-(void)showAlertBanner:(ALAlertBannerView*)alertBanner
-(void)showAlertBanner:(ALAlertBannerView*)alertBanner hideAfter:(NSTimeInterval)delay
{
dispatch_semaphore_t semaphore;
switch (alertBanner.position) {
Expand All @@ -139,8 +160,8 @@ -(void)showAlertBanner:(ALAlertBannerView*)alertBanner
dispatch_async(dispatch_get_main_queue(), ^{
[alertBanner show];

if (self.secondsToShow > 0)
[self performSelector:@selector(hideAlertBanner:) withObject:alertBanner afterDelay:self.secondsToShow];
if (delay > 0)
[self performSelector:@selector(hideAlertBanner:) withObject:alertBanner afterDelay:delay];
});
});
}
Expand Down
1 change: 1 addition & 0 deletions ALAlertBanner/ALAlertBannerView.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ typedef enum {

@property (nonatomic) BOOL isScheduledToHide;
@property (nonatomic) BOOL allowTapToDismiss;
@property (nonatomic, copy) void(^tappedBlock)(ALAlertBannerView *);

@property (nonatomic) NSTimeInterval fadeInDuration;
@property (nonatomic) BOOL showShadow;
Expand Down
24 changes: 13 additions & 11 deletions ALAlertBanner/ALAlertBannerView.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,13 @@ this software and associated documentation files (the "Software"), to deal in

//macros referenced from MBProgressHUD. cheers to @matej
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
#define AL_SINGLELINE_TEXT_HEIGHT(text, font) [text length] > 0 ? [text sizeWithAttributes:nil].height : 0.f;
#else
#define AL_SINGLELINE_TEXT_HEIGHT(text, font) [text length] > 0 ? [text sizeWithFont:font].height : 0.f;
#endif

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
#define AL_SINGLELINE_TEXT_HEIGHT(text, font) [text length] > 0 ? [text sizeWithAttributes:nil].height : 0.f;
#define AL_MULTILINE_TEXT_HEIGHT(text, font, maxSize, mode) [text length] > 0 ? [text boundingRectWithSize:maxSize \
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) \
attributes:nil \
context:NULL].size.height : 0.f;
#else
#define AL_SINGLELINE_TEXT_HEIGHT(text, font) [text length] > 0 ? [text sizeWithFont:font].height : 0.f;
#define AL_MULTILINE_TEXT_HEIGHT(text, font, maxSize, mode) [text length] > 0 ? [text sizeWithFont:font \
constrainedToSize:maxSize \
lineBreakMode:mode].height : 0.f;
Expand Down Expand Up @@ -420,7 +416,13 @@ -(void)push:(CGFloat)distance forward:(BOOL)forward delay:(double)delay

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.state == ALAlertBannerStateVisible && self.allowTapToDismiss)
if (self.state != ALAlertBannerStateVisible)
return;

if (self.tappedBlock) // && !self.isScheduledToHide ...?
self.tappedBlock(self);

if (self.allowTapToDismiss)
[self.delegate hideAlertBanner:self];
}

Expand Down Expand Up @@ -469,7 +471,7 @@ -(void)setInitialLayout
CGSize maxLabelSize = CGSizeMake(parentView.bounds.size.width - (kMargin*3) - self.statusImageView.image.size.width, CGFLOAT_MAX);
CGFloat titleLabelHeight = AL_SINGLELINE_TEXT_HEIGHT(self.titleLabel.text, self.titleLabel.font);
CGFloat subtitleLabelHeight = AL_MULTILINE_TEXT_HEIGHT(self.subtitleLabel.text, self.subtitleLabel.font, maxLabelSize, self.subtitleLabel.lineBreakMode);
CGFloat heightForSelf = titleLabelHeight + subtitleLabelHeight + (self.subtitleLabel.text == nil ? kMargin*2 : kMargin*2.5);
CGFloat heightForSelf = titleLabelHeight + subtitleLabelHeight + (self.subtitleLabel.text == nil || self.titleLabel.text == nil ? kMargin*2 : kMargin*2.5);

CGRect frame = CGRectMake(0, 0, parentView.bounds.size.width, heightForSelf);
CGFloat initialYCoord = 0.f;
Expand Down Expand Up @@ -509,7 +511,7 @@ -(void)updateSizeAndSubviewsAnimated:(BOOL)animated
CGSize maxLabelSize = CGSizeMake(self.parentView.bounds.size.width - (kMargin*3) - self.statusImageView.image.size.width, CGFLOAT_MAX);
CGFloat titleLabelHeight = AL_SINGLELINE_TEXT_HEIGHT(self.titleLabel.text, self.titleLabel.font);
CGFloat subtitleLabelHeight = AL_MULTILINE_TEXT_HEIGHT(self.subtitleLabel.text, self.subtitleLabel.font, maxLabelSize, self.subtitleLabel.lineBreakMode);
CGFloat heightForSelf = titleLabelHeight + subtitleLabelHeight + (self.subtitleLabel.text == nil ? kMargin*2 : kMargin*2.5);
CGFloat heightForSelf = titleLabelHeight + subtitleLabelHeight + (self.subtitleLabel.text == nil || self.titleLabel.text == nil ? kMargin*2 : kMargin*2.5);

CFTimeInterval boundsAnimationDuration = AL_DEVICE_ANIMATION_DURATION;

Expand All @@ -533,9 +535,9 @@ -(void)updateSizeAndSubviewsAnimated:(BOOL)animated
[UIView setAnimationDuration:boundsAnimationDuration];
}

self.statusImageView.frame = CGRectMake(kMargin, (self.frame.size.height/2) - (self.statusImageView.image.size.height/2), self.statusImageView.image.size.width, self.statusImageView.image.size.height);
self.statusImageView.frame = CGRectMake(kMargin, (self.frame.size.height/2) - (self.statusImageView.image.size.height/2), self.statusImageView.image.size.width, self.statusImageView.image.size.height);
self.titleLabel.frame = CGRectMake(self.statusImageView.frame.origin.x + self.statusImageView.frame.size.width + kMargin, kMargin, maxLabelSize.width, titleLabelHeight);
self.subtitleLabel.frame = CGRectMake(self.titleLabel.frame.origin.x, self.titleLabel.frame.origin.y + self.titleLabel.frame.size.height + kMargin/2, maxLabelSize.width, subtitleLabelHeight);
self.subtitleLabel.frame = CGRectMake(self.titleLabel.frame.origin.x, self.titleLabel.frame.origin.y + self.titleLabel.frame.size.height + (self.titleLabel.text == nil ? 0.f : kMargin/2), maxLabelSize.width, subtitleLabelHeight);

if (animated)
[UIView commitAnimations];
Expand Down
7 changes: 6 additions & 1 deletion ALAlertBannerDemo/ALAlertBannerDemo/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,12 @@ -(void)showAlertBannerInView:(UIButton*)button
{
ALAlertBannerPosition position = (ALAlertBannerPosition)button.tag;
ALAlertBannerStyle randomStyle = (ALAlertBannerStyle)(arc4random_uniform(4));
[[ALAlertBannerManager sharedManager] showAlertBannerInView:self.view style:randomStyle position:position title:@"Lorem ipsum dolor sit amet, consectetur adipiscing elit." subtitle:[self randomLoremIpsum]];
[[ALAlertBannerManager sharedManager] showAlertBannerInView:self.view style:randomStyle position:position title:@"Lorem ipsum dolor sit amet, consectetur adipiscing elit." subtitle:[self randomLoremIpsum] tappedHandler:^(ALAlertBannerView *alertBanner) {

NSLog(@"tapped!");
[[ALAlertBannerManager sharedManager] hideAlertBanner:alertBanner];

}];
}

-(void)showAlertBannerInWindow:(UIButton*)button
Expand Down

0 comments on commit 056064c

Please sign in to comment.