Skip to content

Add a cover background view #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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
4 changes: 2 additions & 2 deletions CRToast.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = 'CRToast'
s.version = '0.0.7'
s.version = '0.0.7c'
s.license = 'MIT'
s.summary = 'A modern iOS toast view that can fit your notification needs'
s.homepage = 'https://github.com/cruffenach/CRToast'
s.authors = { 'Collin Ruffenach' => 'cruffenach@gmail.com' }
s.source = { :git => 'https://github.com/cruffenach/CRToast.git', :tag => s.version.to_s }
s.source = { :git => 'https://github.com/mmmilo/CRToast.git', :tag => s.version.to_s }
s.requires_arc = true
s.platform = :ios
s.ios.deployment_target = '7.0'
Expand Down
14 changes: 14 additions & 0 deletions CRToast/CRToast.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,20 @@ extern NSString *const kCRToastSubtitleTextMaxNumberOfLinesKey;

extern NSString *const kCRToastStatusBarStyleKey;

/**
Controls whether or not the cover background should be shown.
The cover background is a view behind the notification, preventing the user
from interacting with the app until the notification is dismissed.
Defaults to `NO`
*/
extern NSString *const kCRToastShowCoverBackgroundKey;

/**
The background color for the cover behind the notification. Expects type `UIColor`.
Defaults to [UIColor blackColor] with an alpha of 0.5f
*/
extern NSString *const kCRToastCoverBackgroundColorKey;

/**
The background color for the notification. Expects type `UIColor`.
*/
Expand Down
89 changes: 80 additions & 9 deletions CRToast/CRToast.m
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ @interface CRToast : NSObject <UIGestureRecognizerDelegate>
//Views and Layout Data

@property (nonatomic, readonly) UIView *notificationView;
@property (nonatomic, readonly) UIView *coverBackgroundView;
@property (nonatomic, readonly) BOOL shouldCoverNotification;
@property (nonatomic, readonly) CGRect notificationViewAnimationFrame1;
@property (nonatomic, readonly) CGRect notificationViewAnimationFrame2;
@property (nonatomic, readonly) UIView *statusBarView;
Expand Down Expand Up @@ -205,6 +207,9 @@ @interface CRToastView : UIView
NSString *const kCRToastSubtitleTextMaxNumberOfLinesKey = @"kCRToastSubtitleTextMaxNumberOfLinesKey";
NSString *const kCRToastStatusBarStyleKey = @"kCRToastStatusBarStyleKey";

NSString *const kCRToastShowCoverBackgroundKey = @"kCRToastShowCoverBackgroundKey";
NSString *const kCRToastCoverBackgroundColorKey = @"kCRToastCoverBackgroundColorKey";

NSString *const kCRToastBackgroundColorKey = @"kCRToastBackgroundColorKey";
NSString *const kCRToastImageKey = @"kCRToastImageKey";

Expand Down Expand Up @@ -248,6 +253,8 @@ @interface CRToastView : UIView
static NSInteger kCRSubtitleTextMaxNumberOfLinesDefault = 0;
static UIStatusBarStyle kCRStatusBarStyleDefault = UIStatusBarStyleDefault;

static BOOL kCRShowCoverBackgroundDefault = NO;
static UIColor * kCRCoverBackgroundColorDefault = nil;
static UIColor * kCRBackgroundColorDefault = nil;
static UIImage * kCRImageDefault = nil;

Expand All @@ -267,28 +274,33 @@ static UIInterfaceOrientation CRGetDeviceOrientation() {
}

static CGFloat CRGetStatusBarHeightForOrientation(UIInterfaceOrientation orientation) {
return (UIDeviceOrientationIsLandscape(orientation)) ?
[[UIApplication sharedApplication] statusBarFrame].size.width :
[[UIApplication sharedApplication] statusBarFrame].size.height;
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
return (UIInterfaceOrientationIsPortrait(orientation)) ?
[[UIApplication sharedApplication] statusBarFrame].size.width :
[[UIApplication sharedApplication] statusBarFrame].size.height;
}
return [[UIApplication sharedApplication] statusBarFrame].size.height;
}

static CGFloat CRGetStatusBarHeight() {
return CRGetStatusBarHeightForOrientation(CRGetDeviceOrientation());
}

static CGFloat CRGetStatusBarWidthForOrientation(UIInterfaceOrientation orientation) {
if (UIDeviceOrientationIsPortrait(orientation)) {
return [UIScreen mainScreen].bounds.size.width;
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
if (UIInterfaceOrientationIsLandscape(orientation)) {
return [UIScreen mainScreen].bounds.size.height;
}
}
return [UIScreen mainScreen].bounds.size.height;
return [UIScreen mainScreen].bounds.size.width;
}

static CGFloat CRGetStatusBarWidth() {
return CRGetStatusBarWidthForOrientation(CRGetDeviceOrientation());
}

static CGFloat CRGetNavigationBarHeightForOrientation(UIInterfaceOrientation orientation) {
return (UIDeviceOrientationIsPortrait(orientation) ||
return (UIInterfaceOrientationIsPortrait(orientation) ||
UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ?
CRNavigationBarDefaultHeight :
CRNavigationBarDefaultHeightiPhoneLandscape;
Expand Down Expand Up @@ -442,6 +454,8 @@ + (void)initialize {
kCRBackgroundColorDefault = [[UIApplication sharedApplication] delegate].window.tintColor ?: [UIColor redColor];
kCRInteractionResponders = @[];

kCRCoverBackgroundColorDefault = [[UIColor blackColor] colorWithAlphaComponent:0.5f];

kCRToastKeyClassMap = @{kCRToastNotificationTypeKey : NSStringFromClass([@(kCRNotificationTypeDefault) class]),
kCRToastNotificationPreferredHeightKey : NSStringFromClass([@(kCRNotificationPreferredHeightDefault) class]),
kCRToastNotificationPresentationTypeKey : NSStringFromClass([@(kCRNotificationPresentationTypeDefault) class]),
Expand Down Expand Up @@ -471,6 +485,8 @@ + (void)initialize {
kCRToastSubtitleTextShadowOffsetKey : NSStringFromClass([[NSValue valueWithCGSize:kCRSubtitleTextShadowOffsetDefault] class]),
kCRToastSubtitleTextMaxNumberOfLinesKey : NSStringFromClass([@(kCRSubtitleTextMaxNumberOfLinesDefault) class]),
kCRToastStatusBarStyleKey : NSStringFromClass([@(kCRStatusBarStyleDefault) class]),
kCRToastShowCoverBackgroundKey : NSStringFromClass([@(kCRShowCoverBackgroundDefault) class]),
kCRToastCoverBackgroundColorKey : NSStringFromClass([UIColor class]),
kCRToastBackgroundColorKey : NSStringFromClass([UIColor class]),
kCRToastImageKey : NSStringFromClass([UIImage class]),
kCRToastInteractionRespondersKey : NSStringFromClass([NSArray class]),
Expand Down Expand Up @@ -518,6 +534,9 @@ + (void)setDefaultOptions:(NSDictionary*)defaultOptions {

if (defaultOptions[kCRToastStatusBarStyleKey]) kCRStatusBarStyleDefault = [defaultOptions[kCRToastStatusBarStyleKey] integerValue];

if (defaultOptions[kCRToastShowCoverBackgroundKey]) kCRShowCoverBackgroundDefault = [defaultOptions[kCRToastShowCoverBackgroundKey] boolValue];
if (defaultOptions[kCRToastCoverBackgroundColorKey]) kCRCoverBackgroundColorDefault = defaultOptions[kCRToastCoverBackgroundColorKey];

if (defaultOptions[kCRToastSubtitleTextKey]) kCRSubtitleTextDefault = defaultOptions[kCRToastSubtitleTextKey];
if (defaultOptions[kCRToastSubtitleFontKey]) kCRSubtitleFontDefault = defaultOptions[kCRToastSubtitleFontKey];
if (defaultOptions[kCRToastSubtitleTextColorKey]) kCRSubtitleTextColorDefault = defaultOptions[kCRToastSubtitleTextColorKey];
Expand Down Expand Up @@ -550,6 +569,13 @@ - (CGRect)notificationViewAnimationFrame2 {
return CRNotificationViewFrame(self.notificationType, self.outAnimationDirection, self.preferredHeight);
}

- (UIView *)coverBackgroundView {
// frame is set by notificationWindow
UIView *coverBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
coverBackgroundView.backgroundColor = self.coverBackgroundColor;
return coverBackgroundView;
}

- (UIView*)statusBarView {
UIView *statusBarView = [[UIView alloc] initWithFrame:self.statusBarViewAnimationFrame1];
[statusBarView addSubview:CRStatusBarSnapShotView(self.displayUnderStatusBar)];
Expand Down Expand Up @@ -621,6 +647,16 @@ - (CGFloat)preferredHeight {
kCRNotificationPreferredHeightDefault;
}

- (BOOL)shouldCoverNotification {
return _options[kCRToastShowCoverBackgroundKey] ?
[self.options[kCRToastShowCoverBackgroundKey] boolValue] :
kCRShowCoverBackgroundDefault;
}

- (UIColor *)coverBackgroundColor {
return _options[kCRToastCoverBackgroundColorKey] ?: kCRCoverBackgroundColorDefault;
}

- (CRToastPresentationType)presentationType {
return _options[kCRToastNotificationPresentationTypeKey] ?
[self.options[kCRToastNotificationPresentationTypeKey] integerValue] :
Expand Down Expand Up @@ -1176,6 +1212,7 @@ @interface CRToastManager () <UICollisionBehaviorDelegate>
@property (nonatomic, strong) UIWindow *notificationWindow;
@property (nonatomic, strong) UIView *statusBarView;
@property (nonatomic, strong) UIView *notificationView;
@property (nonatomic, strong) UIView *coverBackgroundView;
@property (nonatomic, readonly) CRToast *notification;
@property (nonatomic, strong) NSMutableArray *notifications;
@property (nonatomic, copy) void (^gravityAnimationCompletionBlock)(BOOL finished);
Expand Down Expand Up @@ -1245,6 +1282,7 @@ CRToastAnimationCompletionBlock CRToastOutwardAnimationsCompletionBlock(CRToastM
[weakSelf.notifications removeObject:weakSelf.notification];
[weakSelf.notificationView removeFromSuperview];
[weakSelf.statusBarView removeFromSuperview];
[weakSelf.coverBackgroundView removeFromSuperview];
if (weakSelf.notifications.count > 0) {
CRToast *notification = weakSelf.notifications.firstObject;
weakSelf.gravityAnimationCompletionBlock = NULL;
Expand Down Expand Up @@ -1273,6 +1311,10 @@ CRToastAnimationStepBlock CRToastOutwardAnimationsSetupBlock(CRToastManager *wea
[(UIGestureRecognizer*)obj setEnabled:NO];
}];

[UIView animateWithDuration:notification.animateInTimeInterval animations:^{
weakSelf.coverBackgroundView.alpha = 0.0f;
}];

switch (weakSelf.notification.outAnimationType) {
case CRToastAnimationTypeLinear: {
[UIView animateWithDuration:notification.animateOutTimeInterval
Expand Down Expand Up @@ -1360,7 +1402,30 @@ - (void)displayNotification:(CRToast*)notification {
rootViewController.autorotate = notification.autorotate;
rootViewController.notification = notification;

_notificationWindow.rootViewController.view.frame = containerFrame;
if (notification.shouldCoverNotification) {
self.coverBackgroundView = notification.coverBackgroundView;
CGSize backgroundSize = CGSizeMake(_notificationWindow.bounds.size.width, _notificationWindow.bounds.size.height);
// in iOS7, the notification window bounds doesn't change with orientation
// in iOS8, this seems to have been fixed so we don't need to switch the width/height
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
if (UIInterfaceOrientationIsLandscape(CRGetDeviceOrientation())) {
// backgroundSize = CGSizeMake(backgroundSize.height, backgroundSize.width);
}
}
else {
// do nothing, background size doesn't need to be adjusted
}
CGRect cbFrame = CGRectZero;
cbFrame.size = backgroundSize;
_coverBackgroundView.frame = cbFrame;
_coverBackgroundView.alpha = 0.0f;
[_notificationWindow.rootViewController.view addSubview:_coverBackgroundView];
_notificationWindow.rootViewController.view.frame = _notificationWindow.bounds;
}
else {
_notificationWindow.rootViewController.view.frame = containerFrame;
}

_notificationWindow.windowLevel = notification.displayUnderStatusBar ? UIWindowLevelNormal + 1 : UIWindowLevelStatusBar;

UIView *statusBarView = notification.statusBarView;
Expand All @@ -1385,7 +1450,9 @@ - (void)displayNotification:(CRToast*)notification {

__weak __block typeof(self) weakSelf = self;
CRToastAnimationStepBlock inwardAnimationsBlock = ^void(void) {
weakSelf.notificationView.frame = weakSelf.notificationWindow.rootViewController.view.bounds;
CGSize size = weakSelf.notificationView.frame.size;
CGRect resetOrigin = CGRectMake(0, 0, size.width, size.height);
weakSelf.notificationView.frame = resetOrigin;
weakSelf.statusBarView.frame = notification.statusBarViewAnimationFrame1;
};

Expand All @@ -1402,6 +1469,10 @@ - (void)displayNotification:(CRToast*)notification {
}
};

[UIView animateWithDuration:notification.animateOutTimeInterval animations:^{
_coverBackgroundView.alpha = 1.0f;
}];

notification.state = CRToastStateEntering;
switch (notification.inAnimationType) {
case CRToastAnimationTypeLinear: {
Expand Down