// // JTPopupWindow.m // JobTalk // // Created by Xummer on 14-5-20. // Copyright (c) 2014年 BST. All rights reserved. // #import "JTPopOverWindow.h" @interface StatusBarViewController : UIViewController @property (assign, nonatomic) UIStatusBarStyle statusBarStyle; @end @implementation StatusBarViewController - (id)initWithStatusBarStyle:(UIStatusBarStyle)statusBarStyle { self = [super init]; if (!self) { return nil; } self.statusBarStyle = statusBarStyle; return self; } - (UIStatusBarStyle)preferredStatusBarStyle { return _statusBarStyle; } #pragma mark - Route // Below iOS6 use this method - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return UIInterfaceOrientationIsPortrait(interfaceOrientation); } // Above iOS6 use these two methods - (BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } @end @interface JTPopOverWindow () @property (weak, nonatomic) UIWindow *previousKeyWindow; @end @implementation JTPopOverWindow #pragma mark - Life Cycle - (id)init { self = [super initWithFrame:[[UIScreen mainScreen] bounds]]; if (!self) { return nil; } self.windowLevel = UIWindowLevelStatusBar; self.hidden = YES; self.userInteractionEnabled = NO; self.backgroundColor = [UIColor clearColor]; self.vignetteBackground = NO; _statusBarStyle = UIStatusBarStyleDefault; self.rootViewController = [[StatusBarViewController alloc] initWithStatusBarStyle:_statusBarStyle]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setRotation:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; [self setRotation:nil]; return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; } - (void)drawRect:(CGRect)rect { if (_backgroundImage || !_vignetteBackground) return; CGContextRef context = UIGraphicsGetCurrentContext(); size_t locationsCount = 2; CGFloat locations[2] = {0.0f, 1.0f}; CGFloat colors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount); CGColorSpaceRelease(colorSpace); CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); float radius = MIN(self.bounds.size.width , self.bounds.size.height) ; CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation); CGGradientRelease(gradient); } #pragma mark - Setter - (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle { if (_statusBarStyle == statusBarStyle) { return; } _statusBarStyle = statusBarStyle; self.rootViewController = [[StatusBarViewController alloc] initWithStatusBarStyle:_statusBarStyle]; } #pragma mark - Public Method + (instancetype)sharedInstance { static JTPopOverWindow *_sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedInstance = [[self alloc] init]; }); return _sharedInstance; } - (void)addToMainWindow:(UIView *)view { [self setRotation:nil]; if ([self.subviews containsObject:view]) { return; } if (self.hidden) { self.previousKeyWindow = [[UIApplication sharedApplication] keyWindow]; self.alpha = 0.0f; self.hidden = NO; [self makeKeyWindow]; } // if something's been added to this window, then this window should have interaction self.userInteractionEnabled = YES; if (self.subviews.count > 1) { ((UIView*)[self.subviews lastObject]).userInteractionEnabled = NO; } if (_backgroundImage) { UIImageView *backgroundView = [[UIImageView alloc] initWithImage:_backgroundImage]; backgroundView.frame = self.bounds; backgroundView.contentMode = UIViewContentModeScaleToFill; [self addSubview:backgroundView]; _backgroundImage = nil; } [self addSubview:view]; } - (void)removeView:(UIView *)view { [view removeFromSuperview]; UIView *topView = [self.subviews lastObject]; if ([topView isKindOfClass:[UIImageView class]]) { // It's a background. Remove it too [topView removeFromSuperview]; } // It's a view which belong to |StatusBarViewController| [self.rootViewController.view removeFromSuperview]; if (self.subviews.count == 0) { self.hidden = YES; [_previousKeyWindow makeKeyWindow]; _previousKeyWindow = nil; } else { ((UIView*)[self.subviews lastObject]).userInteractionEnabled = YES; } } - (void)reduceAlphaIfEmpty { if (self.subviews.count == 1 || (self.subviews.count == 2 && [[self.subviews objectAtIndex:0] isKindOfClass:[UIImageView class]])) { self.alpha = 0.0f; self.userInteractionEnabled = NO; } } #pragma mark - Private Method - (void)setRotation:(NSNotification*)notification { UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; CGRect orientationFrame = [UIScreen mainScreen].bounds; if( (UIInterfaceOrientationIsLandscape(orientation) && orientationFrame.size.height > orientationFrame.size.width) || (UIInterfaceOrientationIsPortrait(orientation) && orientationFrame.size.width > orientationFrame.size.height) ) { float temp = orientationFrame.size.width; orientationFrame.size.width = orientationFrame.size.height; orientationFrame.size.height = temp; } self.transform = CGAffineTransformIdentity; self.frame = orientationFrame; CGFloat posY = orientationFrame.size.height/2; CGFloat posX = orientationFrame.size.width/2; CGPoint newCenter; CGFloat rotateAngle; switch (orientation) { case UIInterfaceOrientationPortraitUpsideDown: rotateAngle = M_PI; newCenter = CGPointMake(posX, orientationFrame.size.height-posY); break; case UIInterfaceOrientationLandscapeLeft: rotateAngle = -M_PI/2.0f; newCenter = CGPointMake(posY, posX); break; case UIInterfaceOrientationLandscapeRight: rotateAngle = M_PI/2.0f; newCenter = CGPointMake(orientationFrame.size.height-posY, posX); break; default: // UIInterfaceOrientationPortrait rotateAngle = 0.0; newCenter = CGPointMake(posX, posY); break; } self.transform = CGAffineTransformMakeRotation(rotateAngle); self.center = newCenter; [self setNeedsLayout]; [self layoutSubviews]; } @end