Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ALToastView.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
}

+ (void)toastInView:(UIView *)parentView withText:(NSString *)text;
+ (void)toastInView:(UIView *)parentView withText:(NSString *)text andBackgroundColor:(UIColor *)backgroundColor;
+ (void)toastInView:(UIView *)parentView withText:(NSString *)text andDuration:(int)duration;
+ (void)toastInView:(UIView *)parentView withText:(NSString *)text andBackgroundColor:(UIColor *)backgroundColor andDuration:(int)duration;

@end
224 changes: 140 additions & 84 deletions ALToastView.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,16 @@
#import "ALToastView.h"


// Set visibility duration
// Set default visibility duration
static const CGFloat kDuration = 2;

// Set default font size
static const int fontSize = 16;

// Set default padding arround the label
static const int leftPadding = 10;
static const int topPadding = 5;
static const int distanceToBottom = 40;

// Static toastview queue variable
static NSMutableArray *toasts;
Expand All @@ -41,9 +48,11 @@
@interface ALToastView ()

@property (nonatomic, readonly) UILabel *textLabel;
@property (nonatomic) int duration;
@property (nonatomic) UIView *parentView;

- (void)fadeToastOut;
+ (void)nextToastInView:(UIView *)parentView;
+ (void)nextToastInView:(UIView *)parentView withDuration:(int)duration;

@end

Expand All @@ -53,114 +62,161 @@ + (void)nextToastInView:(UIView *)parentView;

@implementation ALToastView

@synthesize textLabel = _textLabel;
@synthesize textLabel = _textLabel, duration = _duration;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - NSObject

- (id)initWithText:(NSString *)text {
if ((self = [self initWithFrame:CGRectZero])) {
// Add corner radius
self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.6];
self.layer.cornerRadius = 5;
self.autoresizingMask = UIViewAutoresizingNone;
self.autoresizesSubviews = NO;

// Init and add label
_textLabel = [[UILabel alloc] init];
_textLabel.text = text;
_textLabel.minimumFontSize = 14;
_textLabel.font = [UIFont systemFontOfSize:14];
_textLabel.textColor = [UIColor whiteColor];
_textLabel.adjustsFontSizeToFitWidth = NO;
_textLabel.backgroundColor = [UIColor clearColor];
[_textLabel sizeToFit];

[self addSubview:_textLabel];
_textLabel.frame = CGRectOffset(_textLabel.frame, 10, 5);
}

return self;
- (id)initWithText:(NSString *)text andParentView:(UIView *)parentView {
if ((self = [self initWithFrame:CGRectZero])) {
self.parentView = parentView;

// Add corner radius
self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.6];
self.layer.cornerRadius = 5;
self.autoresizingMask = UIViewAutoresizingNone;
self.autoresizesSubviews = NO;

// Compute the label's size
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:fontSize]}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){self.parentView.bounds.size.width - 2 * leftPadding, self.parentView.bounds.size.height / 2}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];

// Init and add label
_textLabel = [[UILabel alloc] initWithFrame:rect];
_textLabel.text = text;
_textLabel.font = [UIFont systemFontOfSize:fontSize];
_textLabel.minimumScaleFactor = 12.0/16.0;
_textLabel.textColor = [UIColor whiteColor];
_textLabel.adjustsFontSizeToFitWidth = YES;
_textLabel.backgroundColor = [UIColor clearColor];
_textLabel.numberOfLines = 3;

self.duration = kDuration;

[self addSubview:_textLabel];
_textLabel.frame = CGRectOffset(_textLabel.frame, leftPadding, topPadding);

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
}

return self;
}


- (void)dealloc {
[_textLabel release];

[super dealloc];
[_textLabel release];
[super dealloc];
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Public

+ (void)toastInView:(UIView *)parentView withText:(NSString *)text {
// Add new instance to queue
ALToastView *view = [[ALToastView alloc] initWithText:text];

CGFloat lWidth = view.textLabel.frame.size.width;
CGFloat lHeight = view.textLabel.frame.size.height;
CGFloat pWidth = parentView.frame.size.width;
CGFloat pHeight = parentView.frame.size.height;

// Change toastview frame
view.frame = CGRectMake((pWidth - lWidth - 20) / 2., pHeight - lHeight - 60, lWidth + 20, lHeight + 10);
view.alpha = 0.0f;

if (toasts == nil) {
toasts = [[NSMutableArray alloc] initWithCapacity:1];
[toasts addObject:view];
[ALToastView nextToastInView:parentView];
}
else {
[toasts addObject:view];
}

[view release];
[ALToastView toastInView:parentView withText:text andBackgroundColor:nil andDuration:kDuration];
}

+ (void)toastInView:(UIView *)parentView withText:(NSString *)text andBackgroundColor:(UIColor *)backgroundColor {
[ALToastView toastInView:parentView withText:text andBackgroundColor:backgroundColor andDuration:kDuration];
}

+ (void)toastInView:(UIView *)parentView withText:(NSString *)text andDuration:(int)duration {
[ALToastView toastInView:parentView withText:text andBackgroundColor:nil andDuration:duration];
}

+ (void)toastInView:(UIView *)parentView withText:(NSString *)text andBackgroundColor:(UIColor *)backgroundColor andDuration:(int)duration {
// Add new instance to queue
ALToastView *view = [[ALToastView alloc] initWithText:text andParentView:parentView];

if (backgroundColor) {
view.backgroundColor = backgroundColor;
}

if (duration != kDuration) {
view.duration = duration;
}

CGFloat lWidth = view.textLabel.frame.size.width;
CGFloat lHeight = view.textLabel.frame.size.height;
CGFloat pWidth = parentView.frame.size.width;
CGFloat pHeight = parentView.frame.size.height;

// Change toastview frame
view.frame = CGRectMake((pWidth - lWidth - 2 * leftPadding) / 2., pHeight - lHeight - distanceToBottom, lWidth + 2 * leftPadding, lHeight + 2 * topPadding);
view.alpha = 0.0f;

if (toasts == nil) {
toasts = [[NSMutableArray alloc] initWithCapacity:1];
[toasts addObject:view];
[ALToastView nextToastInView:parentView withDuration:duration];
}
else {
[toasts addObject:view];
}

[view release];
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Private

- (void)fadeToastOut {
// Fade in parent view
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction

animations:^{
self.alpha = 0.f;
}
completion:^(BOOL finished){
UIView *parentView = self.superview;
[self removeFromSuperview];

// Remove current view from array
[toasts removeObject:self];
if ([toasts count] == 0) {
[toasts release];
toasts = nil;
}
else
[ALToastView nextToastInView:parentView];
}];
- (void)orientationChanged:(NSNotification *)notification {
[self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}

- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {
for (ALToastView *view in toasts) {
// Update all toast view's frames
CGFloat lWidth = view.textLabel.frame.size.width;
CGFloat lHeight = view.textLabel.frame.size.height;
CGFloat pWidth = view.parentView.frame.size.width;
CGFloat pHeight = view.parentView.frame.size.height;

view.frame = CGRectMake((pWidth - lWidth - 2 * leftPadding) / 2., pHeight - lHeight - distanceToBottom, lWidth + 2 * leftPadding, lHeight + 2 * topPadding);
}
}

+ (void)nextToastInView:(UIView *)parentView {
if ([toasts count] > 0) {
ALToastView *view = [toasts objectAtIndex:0];

// Fade into parent view
[parentView addSubview:view];
[UIView animateWithDuration:.5 delay:0 options:UIViewAnimationOptionAllowUserInteraction
- (void)fadeToastOut {
// Fade in parent view
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction

animations:^{
view.alpha = 1.0;
} completion:^(BOOL finished){}];

// Start timer for fade out
[view performSelector:@selector(fadeToastOut) withObject:nil afterDelay:kDuration];
}
self.alpha = 0.f;
}
completion:^(BOOL finished){
UIView *parentView = self.superview;
[self removeFromSuperview];

// Remove current view from array
[toasts removeObject:self];
if ([toasts count] == 0) {
[toasts release];
toasts = nil;
}
else
[ALToastView nextToastInView:parentView withDuration:[(ALToastView *)[toasts objectAtIndex:0] duration]];
}];
}

+ (void)nextToastInView:(UIView *)parentView withDuration:(int)duration {
if ([toasts count] > 0) {
ALToastView *view = [toasts objectAtIndex:0];

// Fade into parent view
[parentView addSubview:view];
[UIView animateWithDuration:.5 delay:0 options:UIViewAnimationOptionAllowUserInteraction
animations:^{
view.alpha = 1.0;
} completion:^(BOOL finished){}];

// Start timer for fade out
[view performSelector:@selector(fadeToastOut) withObject:nil afterDelay:duration];
}
}

@end